概念C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数类似。函数名字为关键字operator后面接需要重载的运算符符号。函数原型返回值类型 operator操作符(参数列表)需要注意的几点不能通过连接其他符号来创建新的操作符比如operator必须是已有的操作符重载操作符必须有一个类类型或者枚举类型的操作数用于内置类型的操作符其含义不能改变例如内置的整型不 能改变其含义作为类成员的重载函数时其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this限定为第一个形参参数个数与重载的运算符有关.* 、:: 、sizeof 、?: 、. 注意以上5个运算符不能重载运算符重载作用于左操作数会把左操作数当做第一个参数既然是对自定义类型对象之间的操作符的重载那么它的参数一定有此类型的对象并且需要对对象的成员进行操作这就需要打破封装的限制那么这个函数应该设置为全局的还是类的成员呢有以下几种思路函数设为公有成员变量设为公有不好函数设为公有另外写一个成员函数区获取成员变量的值不好将函数设为类的友元函数可以放入类中作为成员函数推荐1234567891011121314151617181920212223242526272829// 全局的operatorclassDate{public:Date(intyear 1900,intmonth 1,intday 1){_year year;_month month;_day day;}int_year;int_month;int_day;};// 这里会发现运算符重载成全局的就需要成员变量是共有的那么问题来了封装性如何保证// 这里其实可以用我们后面学习的友元解决或者干脆重载成成员函数。booloperator(constDate d1,constDate d2){returnd1._year d2._year d1._month d2._month d1._day d2._day;}intmain(){Date d1(2018, 9, 26);Date d2(2018, 9, 29);cout (d1 d2) endl;return0;}这样的写法就打破了封装让类的成员都暴露了出来这样的损失不太值得。赋值运算符重载赋值操作运算符重载特征如下参数类型相同返回值检测是否给自己赋值返回*this一个类如果没有显式的定义赋值操作符重载编译器会自动生成一个完成对象字节序的拷贝浅拷贝赋值运算符在类中不显式实现时编译器会生成一份默认的此时用户在类外再将赋值运算符重载为全局的就和编译器生成的默认赋值运算符冲突了故赋值运算符只能重载成成员函数。12345678910111213141516171819202122232425262728classDate{public:Date(intyear 1900,intmonth 1,intday 1){_year year;_month month;_day day;}voidDisplay(){cout _year - _month - _day endl;}private:int_year;int_month;int_day;};intmain(){Date d1;Date d2(2018, 10, 1);// 这里d1调用的编译器生成operator完成拷贝d2和d1的值也是一样的。d1 d2;d1.Display();d2.Display();return0;}是不是很像自动生成的拷贝构造那么它也存在一定的问题对于日期类的对象他能很好的完成赋值操作可对于指针类型呢下面的程序会崩溃12345678910111213141516171819202122232425classString{public:String(constchar* str songxin){cout String(const char* str \songxin\) endl;_str (char*)malloc(strlen(str) 1);strcpy(_str, str);}~String(){cout ~String() endl;free(_str);_str nullptr;}private:char* _str;};intmain(){String s1(tanmei);String s2;s2 s1;return0;}原因也是因为浅拷贝的关系导致同一块内存被释放了两次程序崩溃。可以不显式定义赋值操作符重载函数的情况成员变量没有指针成员变量的指针没有管理内存资源注意赋值操作符重载与拷贝构造不同的地方就是拷贝构造是在对象定义时而赋值操作符重载是作用于已经存在的对象。const成员const修饰类的成员函数有点奇怪const怎么能修饰函数呢将const修饰的类成员函数称之为const成员函数const修饰类成员函数实际修饰该成员函数隐含的this指针指向的对象表明在该成员函数中不能对指针指向对象的任何成员进行修改。123456789101112131415161718192021222324252627282930313233343536classDate{public:Date()//构造函数不写的话创建const的对象会报错。:_year(1900),_month(1),_day(1){}voidDisplay(){cout Display () endl;cout year: _year endl;cout month: _month endl;cout day: _day endl endl;}voidDisplay()const{cout Display () const endl;cout year: _year endl;cout month: _month endl;cout day: _day endl endl;}private:int_year;// 年int_month;// 月int_day;// 日};intmain(){Date d1;d1.Display();constDate d2;d2.Display();return0;}const的对象就会调用Display函数会调用哪一个呢注意到上面代码的第18行的函数被const修饰那么这个const有什么作用实际上这个const修饰的是*this表明 *this不可被修改那么const的对象就会调用被const修饰的函数否则可能会出现下面的问题。const对象可以调用非const成员函数吗​ 不可以权限放大。非const对象可以调用const成员函数吗​ 可以权限缩小。const成员函数内可以调用其它的非const成员函数吗​ 不可以权限放大。非const成员函数内可以调用其它的const成员函数吗​ 可以权限缩小。还有一个值得注意的地方上面的代码如果我们不显式定义构造函数的话实例化const的对象时会报错“d2”: 必须初始化 const 对象也就是说编译器认为const对象包括成员无法被赋值应该有初始化操作而默认生成的构造是没有对int有初始化操作的因此报错