C++操作符重载

来源:互联网 发布:淘宝汽车用品店名大全 编辑:程序博客网 时间:2024/06/02 02:27

重载操作符是具有特殊函数名的函数,关键字operator后面接需要定义的操作符符号。操作符重载也是一个函数,具有返回值和形参表。它的形参数目与操作符的操作数目相同,函数调用操作符可以接受任意数目的操作数。使用运算符重载可以提高代码的可读性。

返回类型 operate 操作符(参数列表)--不属于任何的类,是全局的函数

可以被重载的操作符


不可以被重载的操作符


注意:

1、不能通过连接其他符号来创建新的操作符:比如operator@;

voidoperator @(){}

2、重载操作符必须有一个类类型或者枚举类型的操作数

intoperator +(const int _iNum1 , const int _iNum2 )// 报错

{

return ( _iNum1 + _iNum2);

}

typedefenum TEST {one ,two ,three };

intoperator+(const int _iNum1 , const TEST _test )

{

return _iNum1;

}

3、用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不能改变其含义

5、不再具备短求职特性重载操作符不能保证操作符的求值顺序,在重载&&和||中,对每个操作数都要进行求值,而且对操作数的求职顺序不能做规定,因此:重载&&、||和逗号操作符不是好的做法--重载后不能改变运算符的操作对象的个数以及其原有的优先级

6、作为类成员的重载函数,其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this,限定为第一个形参。

CTestoperator+(const CTest test1, const CTest test2)const // 报错

{

return test1;

}

CTestoperator+(const CTest test1)const

{

return test1;

}

7、一般将算术操作符定义为非成员函数,将赋值运算符定义成员函数

8、操作符定义为非类的成员函数时,一般将其定义为类的友元

9、== 和 != 操作符一般要成对重载

10、下标操作符[]:一个非const成员并返回引用,一个是const成员并返回引用

11、解引用操作符*和->操作符,不显示任何参数

13、自增自减操作符前置式++/--必须返回被增量或者减量的引用后缀式操作符必须返回旧值,并且应该是值返回而不是引用返回

14、输入操作符>>和输出操作符<<必须定义为类的友元函数


自增自减操作符的实现


class Date{public:Date(int year = 1996, int month = 4, int day = 15):_year(year),_month(month),_day(day){}Date& operator ++(){_day += 1;return *this;}Date operator ++(int){Date temp(*this);_day += 1;return temp;}private:int _year;int _month;int _day;};int main(){Date d1(2013,12,15);d1++;Date d2;++d2;Date d3(d1);d1<<d2<<d3<<endl;system("pause");return 0;}


输入,输出操作符的实现:需要使用友元函数

友元函数:友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

例如:friend   double FunctionName(参数列表 );

classCPoint{friendclass CTest;public:   CPoint(const double _dX = 0.0f, const double_dY =0.0f): m_dX( _dX), m_dY( _dY)   {}   friend double Distance( const CPoint _pt1,const CPoint _pt2);   //double Distance( const CPoint _pt1, constCPoint _pt2);private:   double m_dX;   double m_dY;};

注意:

a、友元函数可访问类的私有成员,但不是类的成员函数;

b、友元函数不能用const修饰;

c、友元函数可以在类定义的任何地方声明,不受类访问限定符限制;

d、一个函数可以是多个类的友元函数,但只需在各个类中分别声明;

e、友元函数的调用与普通函数的调用和原理相同;

f、其声明可以放在类的私有部分,也可以放在公有部分,无区别

友元类:友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员(当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一个类的友元类);

classCTest{public:   CTest()   {       cout << __FUNCTION__ <<endl;    }   void DisplayCPoint( const CPoint _point)const   {       cout << "X = " <<_point .m_dX << endl;       cout << "Y = " <<_point .m_dY << endl;   }};

友元的优缺点:

优点:提高了程序运行效率

缺点:破坏了类的封装性和隐藏性

注意:

友元关系不能继承;友元关系是单向的,不具有交换性;

友元关系不能传递;


输入,输出操作符的实现:

class Point { private: int x;public: Point(int x1){    x=x1;}friend ostream& operator<<(ostream& cout,const Point& p);//使用友元函数重载<<输出运算符friend istream& operator>>(istream& cin,Point& p);//使用友元函数重载>>输出运算符}; ostream& operator<<(ostream& cout,const Point& p){cout<<p.x<<endl;return cout;}istream& operator>>(istream& cin,Point& p){cin>>p.x;return cin;}//调用: void main(){Point a(1); Point b(2); cin>>a>>b; cout<<a<<b<<endl;}


建议:使用重载操作符,可以令程序更自然、更直观,而滥用操作符重载会使得类难以理解,在实践中很少发生明显的操作符重载滥用。但有些程序员会定义operator+来执行减法操作,当一个重载操作符不明确时,给操作符取一个名字更好,对于很少用的操作,使用命名函数通常比用操作符好,如果不是普通操作,没有必要为简洁而用操作符。


实现一个复数类:

#include <iostream>using namespace std;class Complex{public:Complex(const double _dReal = 2.0f, const double _dImage = 3.0f):_dReal(_dReal),_dImage(_dImage){}Complex(const Complex& complex){_dReal = complex._dReal;_dImage = complex._dImage;}~Complex(){}Complex& operator=(const Complex &complex){if(this != &complex){_dReal = complex._dReal;_dImage = complex._dImage;}return *this;}Complex operator+(const Complex& complex){Complex temp = NULL;temp._dReal = _dReal + complex._dReal;temp._dImage = _dImage + complex._dImage;return temp;}Complex operator-(const Complex& complex){Complex temp = NULL;temp._dReal = _dReal - complex._dReal;temp._dImage = _dImage - complex._dImage;return temp;}Complex operator*(const Complex& complex){Complex temp = NULL;temp._dReal = _dReal * complex._dReal;temp._dImage = _dImage * complex._dImage;return temp;}Complex operator/(const Complex& complex){Complex temp = NULL;temp._dReal = _dReal / complex._dReal;temp._dImage = _dImage / complex._dImage;return temp;}Complex& operator+=(const Complex& complex){_dReal += complex._dReal;_dImage += complex._dImage;return *this;}Complex& operator-=(const Complex& complex){_dReal -= complex._dReal;_dImage -= complex._dImage;return *this;}Complex& operator*=(const Complex& complex){_dReal *= complex._dReal;_dImage *= complex._dImage;return *this;}Complex& operator/=(const Complex& complex){_dReal /= complex._dReal;_dImage /= complex._dImage;return *this;}bool operator>(const Complex& complex){if(_dReal > complex._dReal){return 1;}else if(_dReal < complex._dReal){return 0;}else if(_dReal == complex._dReal){if(_dImage > complex._dImage){return 1;}else {return 0;}}}bool operator>=(const Complex& complex){if(_dReal > complex._dReal){return 1;}else if(_dReal < complex._dReal){return 0;}else if(_dReal == complex._dReal){if(_dImage >= complex._dImage){return 1;}else {return 0;}}}bool operator<(const Complex& complex){if(_dReal < complex._dReal){return 1;}else if(_dReal > complex._dReal){return 0;}else if(_dReal == complex._dReal){if(_dImage < complex._dImage){return 1;}else {return 0;}}}bool operator<=(const Complex& complex){if(_dReal < complex._dReal){return 1;}else if(_dReal > complex._dReal){return 0;}else if(_dReal == complex._dReal){if(_dImage <= complex._dImage){return 1;}else {return 0;}}}bool operator==(const Complex& complex){if(_dReal == complex._dReal && _dImage == complex._dImage){return 1;}else {return 0;}}bool operator!=(const Complex& complex){if(_dReal == complex._dReal && _dImage == complex._dImage){return 0;}else {return 1;}}private:double _dReal;double _dImage;};int main(){Complex c1(1.0f, 1.0f);Complex c2(c1);Complex c3(4.0f, 8.0f);Complex c4 = c1 + c2;Complex c5 = c3 - c1;Complex c6 = c3 * c1;Complex c7 = c3 / c1;Complex c8 = c5;Complex c9;c9 += c3;Complex c10;c10 -= c1;Complex c11;c11 *= c3;Complex c12;c12 /= c1;Complex c13;int ret = c2 > c1;//ret=0时小于或等于, ret=1时大于int temp = c6 < c1;//temp=0时大于或等于, temp=1时小于int ret1 = c1 == c2;//ret1=0时不等于,ret1=1时等于int ret2 = c1 >= c2;//ret2=0时小于,ret2=1时大于或者等于int ret3 = c1 <= c2;//ret3=0时大于,ret3=1时小于或者等于int ret4 = c1 != c3;//ret4=1时不等于,ret4=0时等于   system("pause");return 0;}



0 0
原创粉丝点击