运算符重载
1、重载单目运算符。
class CPoint
{
int x,y;
public:
CPoint(int vx,int vy)
{x=vx;y=vy;}
CPoint(){x=0;y=0;}
void Print();
CPoint operator++(); //前置++运算符的声明
CPoint operator--(); //前置--运算符的声明
};
void CPoint::Print()
{cout<<"("<<x<<","<<y<<")\t";}
CPoint CPoint::operator ++()
{ //前置++运算符的定义
if(x<640) x++; //A
if(y<480) y++; //B
return *this;
}
CPoint CPoint::operator --()
{
if(x>0) x--;
if(y>0) y--;
return *this;
}
void main13_1(void)
{
CPoint p1(10,10),p2(200,200);
for(int i=0;i<5;i++)
(++p1).Print(); //C
cout<<'\n';
for(i=0;i<5;i++)
(--p2).Print();
cout<<'\n';
}
2、友元函数实现例上例中的运算符重载
lass CPoint2
{
int x,y;
public:
CPoint2(int vx,int vy)
{x=vx;y=vy;}
CPoint2(){x=0;y=0;}
void Print();
friend CPoint2 operator++(CPoint2 &); // 用友元函数重载运算符的声明
friend CPoint2 operator--(CPoint2 &);
};
void CPoint2::Print()
{
cout<<"("<<x<<","<<y<<")\t";
}
CPoint2 operator ++(CPoint2 &c) //运算符重载的定义
{
if(c.x<640) c.x++;
if(c.y<480) c.y++;
return c;
}
CPoint2 operator --(CPoint2 &c)
{
if(c.x>0) c.x--;
if(c.y>0) c.y--;
return c;
}
void main13_2(void)
{
CPoint2 p1(10,10),p2(200,200);
for(int i=0;i<5;i++)
(++p1).Print(); //重载运算符的使用
cout<<'\n';
for(i=0;i<5;i++)
(--p2).Print();
cout<<'\n';
}
3、双目运算符的重载
class CThree_d
{
int x,y,z;
public:
CThree_d(int vx,int vy,int vz) //构造函数
{x=vx;y=vy;z=vz;}
CThree_d(){x=0;y=0;z=0;} //无参数的构造函数
CThree_d operator +(CThree_d t); //重载加号"+"
CThree_d operator -(CThree_d t); //重载减号"-"
CThree_d operator =(CThree_d t); //重载赋值符"="
void Print(){cout<<x<<" "<<y<<"\n";}
};
CThree_d CThree_d::operator+(CThree_d t) { //定义两个对象的"+"运算
CThree_d te;
te.x=x+t.x;
te.y=y+t.y;
te.z=z+t.z;
return te; //返回当前对象与t对象之和
}
CThree_d CThree_d::operator-(CThree_d t) //定义两个对象的"-"运算
{
CThree_d te;
te.x=x-t.x;
te.y=y-t.y;
te.z=z-t.z;
return te; //返回当前对象与t对象之差
}
CThree_d CThree_d::operator=(CThree_d t) { //将对象的值赋值给当前对象
x=t.x;
y=t.y;
z=t.z;
return *this;
}
void main13_3(void)
{
CThree_d t1(10,10,10),t2(20,20,20),t3;
t3=t1+t2; //A t1与t2相加给t3
t3.Print(); //显示t3对象的数据成员
t3=t2=t1; //将t1对象多重赋值给t2和t3
t1.Print(); //显示t1,t2,t3的数据成员
t2.Print();
t3.Print();
}
4、定义一个复数类CComplex,在CComplex中包含两个数据成员,实现复数的加减乘除的重载操作
class CComplex //定义复数类
{
float real,imag; //复数的实部和虚部
public:
CComplex(float r,float i){real=r;imag=i;} //带参数的构造函数
CComplex(){real=0;imag=0;} //不带参数的构造函数
void Print(); //复数的输出函数
friend CComplex operator+(CComplex a,CComplex b);
//用友元函数重载复数相加运算符
friend CComplex operator-(CComplex a,CComplex b);
//重载复数相减运算符
friend CComplex operator*(CComplex a,CComplex b);
//重载复数相乘运算符
friend CComplex operator/(CComplex a,CComplex b);
//重载复数相除运算符
};
void CComplex::Print() //定义复数的输出函数
{
cout<<real;
if(imag>0)cout<<"+";
if(imag!=0)cout<<imag<<"i\n";
}
CComplex operator +(CComplex a , CComplex b)
{
CComplex temp;
temp.real=a.real+b.real;
temp.imag=a.imag+b.imag;
return temp;
}
CComplex operator -(CComplex a , CComplex b)
{
CComplex temp;
temp.real=a.real-b.real;
temp.imag=a.imag-b.imag;
return temp;
}
CComplex operator *(CComplex a , CComplex b)
{
CComplex temp;
temp.real=a.real*b.real-a.imag*b.imag;
temp.imag=a.real*b.imag+a.imag*b.real;
return temp;
}
CComplex operator /(CComplex a , CComplex b)
{
CComplex temp;
float tt;
tt=1/(b.real*b.real+b.imag*b.imag);
temp.real=(a.real*b.real+a.imag*b.imag)*tt;
temp.imag=(b.real*a.imag-b.imag*a.real)*tt;
return temp;
}
void main13_4(void)
{
CComplex c1(2.3,4.6) , c2(3.6,2.8) , c3; //定义三个复数对象
c1.Print(); //输出复数c1和c2
c2.Print();
c3=c1+c2; //复数c1,c2相加,结果给c3
c3.Print(); //输出相加结果
c3=c2-c1; //复数c2,c1相减,结果给c3
c3.Print(); //输出相减结果
c3=c2*c1; //复数c1,c2相乘,结果给c3
c3.Print(); //输出相乘结果
c3=c1/c2; //复数c1,c2相除,结果给c3
c3.Print(); //输出相除结果
}
5、用成员函数对自增运算符进行重载
class CIncrease
{
public:
CIncrease(int x){Value=x;}
CIncrease & operator ++(); //前增量
CIncrease operator ++(int); //后增量
void Display(){cout<<"the Value is "<<Value<<endl;}
private:
int Value;
};
CIncrease & CIncrease:: operator ++()
{
Value++;
return *this; //返回的为Value已自加的对象
}
CIncrease CIncrease::operator ++(int)
{
CIncrease temp=*this; //创建一个中间对象,并将它初始化为当前对象
Value++;
return temp; //返回的为Value未自加的对象
}
void main13_5(void)
{
CIncrease n(20);
n.Display();
++n;
n.Display();
(n++).Display();
n.Display();
}
6、用友元函数对自增运算符进行重载
class CIncrease6
{
public:
CIncrease6(int x){Value=x;}
friend CIncrease6 & operator ++(CIncrease6 &); //前增量
friend CIncrease6 operator ++(CIncrease6 &,int); //后增量
void Display()
{
cout<<"the Value is "<<Value<<endl;
}
private:
int Value;
};
CIncrease6 & operator ++(CIncrease6 &a)
{
a.Value++;
return a;
}
CIncrease6 operator ++(CIncrease6 &a,int)
{
CIncrease6 temp(a);
a.Value++;
return temp;
}
void main13_6(void)
{
CIncrease6 n(20);
n.Display();
++n;
n.Display();
(n++).Display();
n.Display();
}
7、利用类的缺省赋值运算符产生的指针悬挂问题。
class CA
{
char *ps;
public:
CA(){ps=0;}
CA(char *s)
{
ps=new char[strlen(s)+1];
strcpy(ps,s);
}
CA & operator=(CA &b); //如果没有该函数将会产生指针悬挂问题
~CA(){if(ps) delete[]ps;}
char *GetS(){return ps;}
};
///*
CA & CA::operator=(CA &b)
{
if(ps) delete[]ps;
if(b.ps)
{
ps=new char [strlen(b.ps)+1];
strcpy(ps,b.ps);
}
else ps=0;
return *this;
}
//*/
void main13_7(void)
{
CA s1("China!"),s2("Computer!");
cout<<"s1="<<s1.GetS()<<'\t';
cout<<"s2="<<s2.GetS()<<'\n';
s1=s2; //A
cout<<"s1="<<s1.GetS()<<'\t';
cout<<"s2="<<s2.GetS()<<'\n';
}
8、对下标运算符进行重载,使之具有检查下表是否越界的功能。
class CArray
{
int len;
float *arp;
public:
CArray(int n=0);
~CArray() {if (arp) delete[]arp;}
int GetLen() const {return len;}
void SetLen(int l)
{
if(l>0)
{
if(arp) delete[]arp;
arp=new float[l];
memset(arp,0,sizeof(float)*l); //A
len=l;
}
}
float & operator[] (int index); // 定义重载的下标运算符
};
CArray::CArray(int n)
{
if(n>0){
arp=new float[n];
memset(arp,0,sizeof(float)*n);
len=n;
}
else{
len=0;
arp=0;
}
}
float & CArray::operator[](int index) //下表运算符的实现
{
if(index>=len||index<0) { //如果参数index超出规定的范围,则输出越界信息
cout<<"\nError:下标"<<index<<"出界!"<<'\n';
exit(2);
}
return arp[index]; //如果不越界,则返回相应的数据
}
void main13_8(void)
{
CArray m1(10),m2(3);
int i;
for(i=0;i<10;i++) m1[i]=i; //重载数组下标的使用
for(i=1;i<11;i++) //B
cout<<m1[i]<<" "; //C
cout<<'\n';
m2[2]=26;
cout<<"m2[2]="<<m2[2]<<'\n';
}
9、通过重载函数调用运算符,实现两维数组下标的合法性的检查。
const int cor1=4;
const int cor2=4;
class CArray9{
float arr[cor1][cor2];
public:
CArray9()
{memset(arr,0,sizeof(float)*cor1*cor2);}
~CArray9() {}
void operator()(int i,int j,float f); //声明函数调用运算符重载函数
float GetElem(int i,int j);
};
void CArray9::operator()(int i,int j,float f){ //函数调用运算符重载函数的实现
if(i>=0&&i<cor1&&j>=0&&j<cor2)
arr[i][j]=f;
else {
cout<<"下标越界!\n";
exit(3);
}
}
float CArray9::GetElem(int i,int j){
if(i<0||j<0||i>=cor1||j>=cor2){
cout<<"下标越界!\n";
exit(3);
}
return arr[i][j];
}
void main13_9(void)
{
CArray9 a;
int i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
a(i,j,(float)i*j); //A 使用重载的函数调用运算符
for(i=0;i<4;i++) {
cout<<'\n';
for(j=0;j<4;j++){ //B
cout<<"a["<<i<<","<<j<<"]="<<a.GetElem(i,j)<<'\t'; //C
if((j+1)%5==0) cout<<'\n';
}
}
cout<<'\n';
}
10、new和delete运算符的重载
const maxpoints=512;
static struct block
{
int x,y;
block *next;
}block1[maxpoints]; //静态结构数组,用来申请内存空间供使用
class CPoint10
{
int x,y;
static block *freelist; //空闲链
static int used; //实际用掉的数组元素个数
public:
CPoint10(int vx=0,int vy=0){x=vx;y=vy;}
void *operator new (size_t); //重载new声明
void operator delete (void *ptr); //重载delete声明
void Print(){cout<<x<<" "<<y<<"\n";}
};
void *CPoint10::operator new(size_t size)
{
block *res=freelist; //将空闲链头给res
if(used<maxpoints) //判断是否元素已用完
res=&block1[used++];
else if(res!=0)
freelist=freelist->next;
cout<<"调用重载的new."<<endl;
return res;
}
void CPoint10::operator delete(void *ptr)
{
((block *)ptr)->next=freelist; //将待释放的内存块插入到链头前
freelist=(block *)ptr;
cout<<"调用重载的delete."<<endl;
}
block *CPoint10::freelist=0; //将静态数据赋初值,空闲链初始为空
int CPoint10::used=0; //所用的数组元素的个数初值为0
void main13_10(void)
{
CPoint10 *pt=new CPoint10(5,7);
pt->Print();
delete pt;
CPoint10 *pt1=::new CPoint10; //调用预定义的new
::delete pt1; //调用预定义的delete
}
11、类型转换函数举例
class CRational
{
public:
CRational(int d,int n){den=d;num=n;}
operator double(); //声明类型转换函数,它将Crational类型型转换为double类型
private:
int den,num;
};
CRational::operator double()
{
return double(den)/double(num);
}
void main(void)
{
CRational r(5,8);
double d=4.7,e,f;
d+=r; //A 将CRational类型隐式转换为double类型
e=CRational(r); //B 将CRational类型强制转换为double类型
f=(CRational)r; //C 强制转换的另一种形式
cout<<d<<'\t'<<e<<'\t'<<f<<endl;
}

浙公网安备 33010602011771号