1、实验目的和要求
(1)掌握运算符重载的语法要点,理解成员函数与友元函数重载运算符的区别。
(2)掌握各种运算符的重载方法,理解引用形式作为参数和返回值的特点。
2、实验内容
(1)定义描述平面点类Point,重载减号运算符计算两个点的距离,分别用成员函数与友元函数实现。重载运算符<<输出点的坐标[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)重载算术运算符“+”、“-”、“*”、“/”,使之能够适用于有理数的四则运算。
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)重载运算符“+”,实现两个集合对象的合并操作,重载运算符“*”,求两个集合对象的交集;例如Set s, s1, s2; s =s1+s2; s = s1* s2;
3)重载赋值运算符=和复合赋值运算符-= , 实现两个集合对象的赋值操作与差集操作。例如Set s1,s2;s1 = s2; s1-=s2; 集合S1中去掉S2中存在的元素。
#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)定义描述时间的Time类,包括数据成员小时hour、分钟minute和秒second,定义相关函数实现如下操作:
1)重载运算符“+”与“-”,能够实现时间对象与整数秒的加减操作。
2)重载运算符“<<”输出时间对象,能够按照“小时:分钟:秒”的方式显示时间。
3)重载运算符“++”与“--”,要求能够实现时间的合理自增自减功能(秒数的增减)。
(5)设计字符串类String,若有String类对象s1、s2和s3,重载运算符实现如下操作:
1)重载“+”实现字符串连接功能,使表达式s1= s2+s3成立;
2)重载“<”判断两个字符串的大小,如 if(s1 < s2)cout<<s1<<”<”<<s2;
3)重载“<<”与“>>”,实现字符串的输入与输出操作,如cin>>s2;cout<<s2<<endl;
4)重载运算符“()”,从字符串对象中返回一个子串。如s1(2,4)表示返回从子串,即从s[2](s1第3个字符)开始的子串(包括s1[2]、s1[3]和s1[4]三个字符)。
(6)【选作】开发多项式类Polynomial,多项式的每一项用数组或结构体表示,每项包含一个系数和一个指数。例如2x4的指数为4,系数为2。请开发一个完整的Polynomial类,包括构造函数、析构函数以及get函数和set函数。该类还要提供下述重载的运算符:
1)重载运算符“+”和“-”,将两个多项式相加或相减。
2)重载乘法运算符“*”,将两个多项式相乘。
3)重载赋值运算符“=”,将一个多项式赋给另外一个多项式。