运算符重载总结

一、重载运算符的限制

1,不能被重载的运算符: *   ::  ?:    sizeof

2,重载运算符函数可以对运算符做出新的解释,定义用户所需要的各种操作,运算符重载后,原有的基本语义不变

1)不改变运算符的优先级

2)不改变运算符的结合性

3)不改变运算符所需要的操作数

注:重载运算符只是扩展了运算符的应用范围,只是重新定义含义,但不能创建新的运算符

二、运算符的语法形式

1,运算符函数是一种特殊的成员函数或友元函数

格式:  类型  类名::operatpr op(参数表)

{

//相对于该类定义的操作

}

注:类型—函数的返回值类型

类名—要重载该运算符的类

op—要重载的运算符

参数表—列出该运算符所需要的操作数

2,例如:classCalculator

{

public:

void operator ++();

private:

unsigned int value;

};

void class::operator++()

{

 //函数体

}

三、用成员函数或友元函数重载运算符

1,一元运算符:一元运算符不论前置还是后置,都要求有一个操作数 object op或op object

1)当重载为成员函数时,编译器解释为object.operator op()

注:函数所需要的操作数由对象object通过this指针隐含传递,所以参数表为空

2)当重载为友元函数时,

Operator op(object)

2,二元运算符

任何二元运算符都要求有左右操作数,objectL op objectR

1)当重载为成员函数时, object.Operatorop(objectR)

2)当重载为友元函数时,operatorop(objectL,objectR)

左右操作数都由参数传递

3,用成员函数重载运算符

1)当一元运算符的操作数,或者二元运算符的左操作数是该类的一个对象时,重载运算符函数一般定义为成员函数

例如:重载+

class TriCoor

{

public:

  TriCoor operator+(TriCoort);

private:

  Int x,y,z;

};

TriCoor::TriCoor (int mx,int my,int mz)

{  x=mx;

   y=my;

z=mz;

}

TriCoor::TriCoor operator +(TriCoor t)

{

 triCoor temp;

 temp.x=x+t.x;

 temp.y=y+t.y;

 temp.z=z+t.z;

 return temp;

}

注:重载运算符+的成员函数参数表只有一个参数,另一个操作数由this指针隐含传递

语句:temp.x=x+t.x;相当于temp.x=this->x+t.x;其中,this是操作的左操作数

4,用友元函数重载运算符

friend Complex operator +(Complex,Complex);

两个操作数完成

三、几个典型运算符的重载

<一>重载++与- -

1,前置自增表达式

++Aobject

1)若用成员函数重载,则编译器解释为

Aobject operator ++()

对应的函数原型为

A&A::operator ++()

注:此时括号中没有参数

2)若用友元函数重载,则编译器解释为:

friend A&operator ++(A&);

注:友元函数必须要带参数

2,后置自增表达式

Aobject ++

成员函数重载的解释为

Aobject.operator++(0)

对应的函数原型为;A&A::operator ++(int);

注:此时括号内是有参数的,但是这个参数只是为了和前置++进行区分,并没有实际作用

2)友元函数重载的解释为

operater ++(Aobject,0)

 

对应的函数原型为:friend A& operator ++(A&,int);

注:第一个操作数是对象,要进行操作,但是第二个对象只是为了区分前置,不起任何作用

<二>重载- -

重载自减运算符与重载自加运算符格式相同

<三>重载赋值运算符=

赋值运算符重载用于对象的数据的复制,只能用于成员函数重载,重载函数原型为:

类名&类名::operator = (类名);

注:括号中的类名是指的要赋值的对象

例:

#include<bits/stdc++.h>

using namespace std;

class Name

{

public:

   Name (char *pN="\0");//构造函数

   Name (const Name &);//复制构造函数

   Name &operator =(Name);//重载赋值号

   ~Name();

protected:

   char *pName;

   int size;

};

Name :: Name(char *pN)

{

   cout<<"Constructing "<<pN<<endl;

   size =strlen(pN);

   pName=new char[size+1];

   if(pName!=0)strcpy_s(pName,size+1,pN);

 

}

Name ::Name(const Name &Obj)

{

   cout<<"Copying "<<Obj.Pname<<"into itsown block\n";

   size=Obj.size;

   pName=new char[size+1];

   if(pName!=0)strcpy_s(pName,size+1,Obj.pName);

}

Name &Name operator =(Name Obj)

{

   delete []pName;

   size=Obj.size;

   pName=new char[size +1];

   if(pName!=0)strcpy_s(pName,size+1,Obj.pName);

}

int main()

{

   Name Obj1("zhangsan");

   Name Obj2=Obj1;

   Name Obj3("noname");

   Obj3=Obj2=Obj1;

}

注:1,重载赋值运算符函数与复制构造函数的实现十分相似,但是不同的是,重载函数返回*this

2,复制构造函数在实现成员的复制时,用于对象的初始化,重载运算符用于程序运行时修改对象的数据

3,重载赋值运算符的实现必须是成员函数

<四>重载[ ],( )

1,重载下标运算符[ ]

[ ]是二元运算符,用于访问数据对象的元素

格式  对象[表达式]

例如:类X有重载函数 int &X::operator [ ] (int)

其中,x是X的对象,则调用的函数表达式x[k]的意思就是调用x中的第k个元素

被解释为: x.operator[ ](k)

2,重载函数调用运算符( )

 ( )是一个二元运算符,

格式:  对象 (表达式表)

其中,表达式表可以为空

3,重载输入输出流

函数名:

       输出流: operator<<(参数表)

       输入流:operator>>(参数表)

参数表:固定,两个参数均用引用&

 输出流: 必须是两个参数:对输出流ostream&和 对象

第一个操作数cout,定义在文件iostream中,是标准类类型ostream的对象的引用     如:ostream& cout,const Point& p

 输入流:必须是两个参数:对输入流ostream& 和 对象

   第一个操作数是cin,定义在文件iostream,实际上是标准类类型istream的对象的引用

   如:instream& cin,const Point& p

函数调用:

       输出流: 显式调用:cout<<对象

                       隐式调用: operator<<(cout,对象)

       输入流:显式调用:cin>>对象

                       隐式调用: operator>>(cin,对象)

返回类型:返回类型固定 + 使用返回函数引用(满足连续输出)

       输出流: 返回ostream&

                       如:ostream& operator<<(ostream&cout,const Point& p)

       输入流:返回:istream&

                        如:istream& operator>>(istream& cin,Point& p)

注:输入输出操作符的重载必须使用友元函数,因为成员函数要求是有对象调用,则第一个参数必须是类的对象,但是<<和>>第一个参数是流的对象引用。故,不能使用成员函数

四、学习心得

1,一般的运算符只能在一些数据之间进行运算,重载运算符解决了对象之间的运算,、

2,不管是成员函数重载还是友元函数重载,运算符的使用方法都相同,但是由于他们传递参数的方法不同,因此导致实现的代码不同,应用场合也不同。

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
定义表示形状的抽象类及相应的派生类,并实现相关操作符重载。 (1)定义表示形状的抽象类Shape: 添加公有成员函数double Area(),用于计算形状面积;定义为纯虚函数; 添加公有成员函数void Show(),用于显示形状信息,定义为纯虚函数; 定义虚的析构函数; 重载比较操作符:==、>和<,用于比较两个形状面积的大小关系,返回值类型为bool,可以定义为成员函数或友元函数。 (2)从形状类Shape派生矩形类Rectangle: 添加double型的保护数据成员:rectWidth和rectHeight,分别表示矩形的宽度和高度; 定义带参构造函数; 重定义公有成员函数Show,打印矩形的宽度和高度,输出格式为“W: 宽度; H: 高度; Area: 面积”; 重定义公有成员函数Area,计算矩形面积。 (3)从形状类Shape派生椭圆类Ellipse: 添加double型的保护数据成员:rectWidth和rectHeight,分别表示椭圆外接矩形的宽度和高度; 定义带参构造函数; 重定义公有成员函数Show,打印椭圆外接矩形的宽度和高度,输出格式为“W: 宽度; H: 高度; Area: 面积”; 重定义公有成员函数Area,计算椭圆面积。 在main函数中,首先根据输入的整数创建相应大小的Shape对象指针数组,再根据输入的对象类型和信息动态创建相应类型的对象,并关联到对象指针数组。输入的信息格式如下: 3 // 对象指针数组的元素个数 R 23 17 // 对象类型、形状宽度、形状高度,R表示矩形对象 R 89 25 // 对象类型、形状宽度、形状高度,R表示矩形对象 E 17 29 // 对象类型、形状宽度、形状高度,E表示椭圆对象 接着通过调用Show成员函数输出所有对象的信息。 然后输出面积相等的形状对象的信息(要求使用重载运算符“==”来判断对象的面积是否相等),输出格式如下: Area of Shape[i] is equal to Shape[j] 最后将所有形状对象按面积从大到小排序(要求使用重载运算符“>”来判断对象的面积的大小关系),并输出排序后的对象信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值