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)重载赋值运算符“=”,将一个多项式赋给另外一个多项式。