1. 赋值运算符重载
赋值运算符重载也是类的默认成员函数
1.1 运算符重载
- 当运算符被用于类类型对象时,C++ 语言允许我们通过运算符重载的形式指定新的含义。C++ 规定类类型对象使用运算符时,必须转换成调用对应运算符重载,若没有对应的运算符重载,编译器会报错。
- 运算符重载是具有特殊名字的函数,他的名字是由 operator 和后面定义的运算符共同构成,和其他函数一样他也具有其返回类型和参数列表以及函数体。
- 重载运算符函数的参数个数和该运算对象数量一样多。一元运算符有一个参数,二元运算符有两个参数,二元运算符的左侧运算对象传给第一个参数,右侧运算对象传给第二个参数。
- 如果一个重载运算符函数是成员函数,则他第一个运算对象默认传给隐式的 this 指针,因此 运算符重作为成员函数时,参数比运算对象少一个。
- 运算符重载以后,其优先级和结合性与对应的内置类型运算符保持一致。
- 不能通过连接语法中没有的符号来创建新的操作符:比如 operator@ 。
- .* : : sizeof ?: . 注意以上五个运算符不能重载。( .* 类成员函数指针的解引用)
- 重载操作符至少有一个类类型参数,不能通过运算符重载改变内置类型对象的含义,如 int operator+(int x ,int y)。
- 一个类需要重载那些运算符,是看哪些运算符重载有意义,比如 Date 类重载 operator-,就有意义,但是重载 operator+ 就没有意义。
- 重载++运算符时,有前置++和后置++,运算符重载函数名都是 operator++ ,无法很好区分。C++规定,后置++重载时,增加一个 int 形参,跟前置++构成函数重载,方便区分。
- 重载 << 和 >> 时,需要重载为全局函数,因为重载为成员函数,this指针默认抢占第一个形参位置,第一个形参位置是左侧运算对象,调用调用时就变成了 对象<<cout,不符合使用习惯和可读性。重载为全局函数把 ostream / istream 放到第一个形参位置就可以了,第二个形参位置是类类型对象。




1.2 赋值运算符重载
赋值运算符重载是一个默认成员函数,用于完成两个已经存在的对象的直接拷贝赋值,这里要注意跟拷贝构造进行区分,拷贝构造用于一个对象拷贝初始化给另外一个要创建的对象。
赋值运算符重载的特点:
- 赋值运算符重载是一个运算符重载,规定必须重载成成员函数。赋值运算重载的参数建议写成const 当前类型引用,否则会传值传参会有拷贝。
- 有返回值,且建议写成当前类类型的引用,引用返回会提升效率,有返回值目的是为了支持连续赋值场景。
- 没有显示实现时,编译器会自动生成一个默认赋值运算符重载,默认赋值运算符重载行跟默认拷贝构造函数类似,对内置类型成员成员变量会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的赋值重载函数。
- 像 Date类这样的成员变量全是内置类型且没有指向什么资源,编译器自动生成赋值运算符重载就可以完成需要的拷贝,所以不需要我们显示实现赋值运算符重载。如果有的类指向了资源,编译器自动生成的赋值运算符重载就只能完成浅拷贝/值拷贝,一般就不符合我们的需求,所以我们要自己实现深拷贝。这里还有一个技巧,如果一个类显示实现了析构并释放了资源,那么他就要显示写赋值运算符重载,否则就不需要。




2. 取地址运算符重载
2.1 const成员函数
- const修饰的成员函数称之为 const成员函数,const修饰成员函数放置到放到成员函数参数列表后面。
- const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。const修饰Date类的Print成员函数,Print隐含得到this指针由Date* const this变成了const Date* const this。
2.2 取地址运算符重载
取地址运算符重载分为普通取地址运算符重载和const取地址运算符重载,一般这两个函数编译器自动生成的就够我们用了,不需要去显示实现。除非一些很特殊的场景,如如我们不想让别人取到当前类对象的地址,就可以自己实现一下,就可以自己实现一份,然后胡乱返回一个地址。






