実験4演算子のリロード
10193 ワード
1、実験目的と要求
(1)演算子のリロードの文法的要点を把握し,メンバー関数と友元関数のリロード演算子の違いを理解する.
(2)各種演算子のリロード方法を把握し,参照形式がパラメータと戻り値としての特徴を理解する.
2、実験内容
(1)平面点クラスPointを記述し、リロードマイナス演算子は2点の距離を計算し、それぞれメンバー関数と友元関数で実現する.リロード演算子<<出力点の座標[x,y]は、クラスおよび関連関数の定義を与える.
(2)有理数を記述するRationalクラスは以下のようになりますが,クラスの他のメンバーが様々な演算を実行できるように補足してください.
Class Rational
{
long numerator ;//分子
long denominator ;//分母
........
};
1)算術演算子「+」、「-」、「*」、「/」を再ロードし、有理数の4則演算に適用できるようにする.
2)2つの有理数を比較できるように、比較演算子">"、"<="と"=="を再ロードします.
3)1/2,-1/3のような正規の方法でスコアを出力できるように、演算子「<<」をリロードします.分母は0にできません.
(3)集合クラスSetを定義し、最大100個の重複しない整数を格納し、集合の以下の操作を実現する.
1)ある整数要素を追加する場合、集合に重複要素がないことを保証する.指定した要素を削除し、その要素を検索すると、集合からその要素を削除します.
2)演算子「+」を再ロードし、2つの集合オブジェクトの連結操作を実現し、演算子「*」を再ロードし、2つの集合オブジェクトの交差を求める.例えばSet s,s 1,s 2;s =s1+s2; s = s1* s2;
3)賦値演算子=と複合賦値演算子-=を再ロードし、2つの集合オブジェクトの賦値操作と差セット操作を実現する.例えば、Set s 1,s 2;s1 = s2; s1-=s2; 集合S 1では、S 2に存在する要素を削除する.
(4)データメンバーの時間hour、分minute、秒secondを含む時間を記述するTimeクラスを定義し、関連関数を定義して以下の操作を実現する.
1)演算子「+」と「-」をリロードし、時間オブジェクトと整数秒の加減を実現します.
2)リロード演算子「<<<」は時間オブジェクトを出力し、「時間:分:秒」のように時間を表示することができる.
3)演算子「+」と「--」を再ロードし、時間の合理的な自増自減機能(秒数の増減)を実現することを要求する.
(5)文字列クラスStringを設計し、Stringクラスオブジェクトs 1、s 2、s 3があれば、リロード演算子は以下の操作を実現する.
1)「+」を再ロードして文字列接続機能を実現し、式s 1=s 2+s 3を成立させる.
2)if(s 13)「<<」>「>」を再ロードし、cin>>s 2のような文字列の入力と出力操作を実現する.cout<4)演算子「()」をリロードし、文字列オブジェクトからサブストリングを返します.s 1(2,4)のように、s[2](s 1[2](s 1)から始まるサブ列(s 1[2]、s 1[3]およびs 1[4]の3文字を含む)を返す.
(6)【オプション】多項式クラスPolynomialを開発します.多項式の各項目は配列または構造体で表され、各項目は1つの係数と1つの指数を含みます.たとえば、2 x 4の指数は4で、係数は2です.構造関数、構造関数、get関数、set関数を含む完全なPolynomialクラスを開発してください.このクラスには、次のようなリロード演算子も用意されています.
1)演算子「+」と「-」を再ロードし、2つの多項式を加算または減算します.
2)乗算演算子「*」を再ロードし、2つの多項式を乗算します.
3)代入演算子"="を再ロードし、1つの多項式を別の多項式に割り当てます.
(1)演算子のリロードの文法的要点を把握し,メンバー関数と友元関数のリロード演算子の違いを理解する.
(2)各種演算子のリロード方法を把握し,参照形式がパラメータと戻り値としての特徴を理解する.
2、実験内容
(1)平面点クラスPointを記述し、リロードマイナス演算子は2点の距離を計算し、それぞれメンバー関数と友元関数で実現する.リロード演算子<<出力点の座標[x,y]は、クラスおよび関連関数の定義を与える.
#include <iostream>
#include <cmath>
using namespace std;
class Point
{
public:
Point(int a= 0, int b = 0):x(a),y(b) {}
void setPoint(int a, int b)
{
x=a;
y=b;
}
double operator -(const Point& p);
friend double operator -(Point& p1,Point& p2);
friend ostream& operator <<(ostream& out,const Point& p);// "<<"
private:
int x, y; //
};
double Point::operator -(const Point& p)
{
return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
}
double operator -(Point& p1,Point& p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
ostream& operator <<(ostream& out,const Point& p)
{
cout<<"["<<p.x<<","<<p.y<<"]";
return out;
}
int main()
{
Point p1(2,1),p2;
double d=p1-p2; //
cout<<p1<<"->"<<p2<<"="<<d<<endl; // [2,1]->[0,0]=2.23
return 0;
}
(2)有理数を記述するRationalクラスは以下のようになりますが,クラスの他のメンバーが様々な演算を実行できるように補足してください.
Class Rational
{
long numerator ;//分子
long denominator ;//分母
........
};
1)算術演算子「+」、「-」、「*」、「/」を再ロードし、有理数の4則演算に適用できるようにする.
2)2つの有理数を比較できるように、比較演算子">"、"<="と"=="を再ロードします.
3)1/2,-1/3のような正規の方法でスコアを出力できるように、演算子「<<」をリロードします.分母は0にできません.
#include<iostream>
#include<cmath>
using namespace std;
class Rational
{
public:
Rational(int n=1,int d=1);
Rational operator +(const Rational &a);//
Rational operator -(const Rational &a);
Rational operator *(const Rational &a);
Rational operator /(const Rational &a);
bool operator <(const Rational &a)const;
bool operator >(const Rational &a)const;
bool operator ==(const Rational &a)const;
friend ostream& operator << (ostream& out,const Rational &a);
void simple();//
private:
int numerator ; //
int denominator ; //
};
Rational::Rational(int n,int d):numerator(n),denominator(d) {}
Rational Rational::operator +(const Rational &a)
{
Rational temp;
temp.numerator=this->numerator*a.denominator+a.numerator*this->denominator;
temp.denominator=this->denominator*a.denominator;
temp.simple();
return temp;
}
Rational Rational::operator-(const Rational &a)
{
Rational temp;
temp.numerator=this->numerator*a.denominator-this->denominator*a.numerator;
temp.denominator=this->denominator*a.denominator;
temp.simple();
return temp;
}
Rational Rational::operator*(const Rational &a)
{
Rational temp;
temp.numerator=this->numerator*a.numerator;
temp.denominator=this->denominator*a.denominator;
temp.simple();
return temp;
}
Rational Rational::operator/(const Rational &a)
{
Rational temp;
temp.numerator=this->numerator*a.denominator;
temp.denominator=this->denominator*a.numerator;
temp.simple();
return temp;
}
bool Rational::operator <(const Rational &a)const
{
if(this->numerator*a.denominator<this->denominator*a.numerator)return true;
else return false;
}
bool Rational::operator >(const Rational &a)const
{
if(this->numerator*a.denominator>this->denominator*a.numerator)return true;
else return false;
}
bool Rational::operator ==(const Rational &a)const
{
if(this->numerator*a.denominator==this->denominator*a.numerator)return true;
else return false;
}
ostream& operator<<(ostream& out,const Rational &a)
{
if(a.denominator!=0)out<<a.numerator<<'/'<<a.denominator;
else out<<'0';
return out;
}
void Rational::simple()
{
int temp=numerator,a=numerator,b=denominator;
while(temp!=0)//
{
temp=b%a;
b=a;
a=temp;
}
numerator=numerator/b;
denominator=denominator/b;
}
int main()
{
Rational a(1,2);
Rational b(1,3);;
cout<<"a+b="<<a+b<<endl;
cout<<"a-b="<<a-b<<endl;
cout<<"a*b="<<a*b<<endl;
cout<<"a/b="<<a/b<<endl;
if(a>b)
{
cout<<"a>b"<<endl;
}
else if(a<b)
{
cout<<"a<b"<<endl;
}
else if(a==b)
{
cout<<"a==b"<<endl;
}
return 0;
}
(3)集合クラスSetを定義し、最大100個の重複しない整数を格納し、集合の以下の操作を実現する.
1)ある整数要素を追加する場合、集合に重複要素がないことを保証する.指定した要素を削除し、その要素を検索すると、集合からその要素を削除します.
2)演算子「+」を再ロードし、2つの集合オブジェクトの連結操作を実現し、演算子「*」を再ロードし、2つの集合オブジェクトの交差を求める.例えばSet s,s 1,s 2;s =s1+s2; s = s1* s2;
3)賦値演算子=と複合賦値演算子-=を再ロードし、2つの集合オブジェクトの賦値操作と差セット操作を実現する.例えば、Set s 1,s 2;s1 = s2; s1-=s2; 集合S 1では、S 2に存在する要素を削除する.
#include<iostream>
#include<cstring>
using namespace std;
class Set
{
public:
Set(int p_size = 1);
Set(const Set& p_Set);
~Set();
int getLength()
{
return length ;
}
void addItem(int p_item);
void delItem(int p_item);
Set operator + (Set& p_set);
Set operator * (Set& p_set);
Set& operator = (const Set& p_set);
Set& operator -= (Set& p_set);
friend ostream& operator << (ostream& x , Set& p_set);
int operator [](int index) const;
private:
int size;
int length;
int* data;
};
Set::Set(int p_size)
{
size = (p_size <= 0) ? 1 : ((p_size > 100) ? 100 : p_size);
data=new int[ size ];
length=0;
memset(data,0,sizeof(data));
}
Set::Set(const Set &p_Set)
{
size = p_Set.size;
length = p_Set.length;
data = new int[size];
for(int i = 0 ; i < length ; i ++)
data[i] = p_Set[i];
}
Set::~Set()
{
if(data)
delete []data;
size = 0;
length = 0;
}
int Set::operator [](int index) const
{
return data[(index < 0) ? 0 : ((index >= length) ? length - 1 : index) ];
}
void Set::addItem(int p_item)
{
if(size == 100)
{
cout << " !" << endl;
return;
}
if(length == size && size < 100)
{
size = ((size + 20) > 100) ? 100 : (size + 20);
int* temp = new int[size];
for(int i = 0 ; i < length ; i ++)
temp[i] = data[i];
if(data)
delete []data;
data = temp;
}
for(int i = 0 ; i < length ; i ++)
{
if(p_item == data[i])
{
cout << " !" << endl;
return;
}
}
data[ length ] = p_item;
length ++;
}
;
void Set::delItem(int p_item)
{
for(int i = 0 ; i < length ; i ++)
{
if(p_item == data[i])
{
if(i < length - 1)
for(int j = i ; j < length - 1 ; j ++)
data[j] = data[j +1];
length --;
}
}
}
Set Set::operator +(Set &p_set)
{
Set s(*this);
int flag ;
for(int i = 0 ; i < p_set.length ; i ++)
{
flag = 1;
for(int j = 0 ; j < s.length ; j ++)
if(s[j] == p_set[i])
{
flag = 0;
break;
}
if(flag)
s.addItem(p_set[i]);
}
return s;
}
Set Set::operator * (Set &p_set)
{
Set s(50);
for(int i = 0 ; i < p_set.length ; i ++)
{
for(int j = 0 ; j < length ; j ++)
if(data[j] == p_set[i])
{
s.addItem(data[j]);
}
}
return s;
}
Set& Set::operator = (const Set &p_set)
{
size = p_set.size;
length = p_set.length;
if(data)
delete []data;
data = new int[size];
for(int i = 0 ; i < length ; i ++)
data[i] = p_set[i];
return *this;
}
Set& Set::operator -=(Set &p_set)
{
for(int i = 0 ; i < p_set.length ; i ++)
{
for(int j = 0 ; j < length ; j ++)
if(data[j] == p_set[i])
{
this->delItem(data[j]);
}
}
return *this;
}
ostream& operator << (ostream& out , Set &p_set)
{
for(int i = 0 ; i < p_set.length ; i ++)
out << p_set[i] << ' ';
return out;
}
int main()
{
Set s1(5),s2(4),s3;
for(int i = 0 ; i < 5 ; i ++)
s1.addItem(i + 1);
s1.addItem(5);
cout << s1 << endl;
for(int i = 1 ; i <= 4 ; i ++)
s2.addItem(i * 2);
cout<<s2<<endl;
Set s=s1+s2;
cout<<s<<endl;
s=s1*s2;
cout<<s<<endl;
s1 -= s2;
cout << s1 << endl;
s3 = s2;
cout << s3 << endl;
return 0;
}
(4)データメンバーの時間hour、分minute、秒secondを含む時間を記述するTimeクラスを定義し、関連関数を定義して以下の操作を実現する.
1)演算子「+」と「-」をリロードし、時間オブジェクトと整数秒の加減を実現します.
2)リロード演算子「<<<」は時間オブジェクトを出力し、「時間:分:秒」のように時間を表示することができる.
3)演算子「+」と「--」を再ロードし、時間の合理的な自増自減機能(秒数の増減)を実現することを要求する.
(5)文字列クラスStringを設計し、Stringクラスオブジェクトs 1、s 2、s 3があれば、リロード演算子は以下の操作を実現する.
1)「+」を再ロードして文字列接続機能を実現し、式s 1=s 2+s 3を成立させる.
2)if(s 1
(6)【オプション】多項式クラスPolynomialを開発します.多項式の各項目は配列または構造体で表され、各項目は1つの係数と1つの指数を含みます.たとえば、2 x 4の指数は4で、係数は2です.構造関数、構造関数、get関数、set関数を含む完全なPolynomialクラスを開発してください.このクラスには、次のようなリロード演算子も用意されています.
1)演算子「+」と「-」を再ロードし、2つの多項式を加算または減算します.
2)乗算演算子「*」を再ロードし、2つの多項式を乗算します.
3)代入演算子"="を再ロードし、1つの多項式を別の多項式に割り当てます.