条款15: 让operator=返回*this的引用
试图让用户自定义类型尽可能和固定类型的工作方式相似;
固定类型赋值可以:
1
2
|
int
w, x, y, z;
w = x = y = z = 0;
|
用户自定义类型也可以:
1
2
|
string w, x, y, z;
// string 是由标准C++库“自定义”的类型(参见条款49)
w = x = y = z =
"Hello"
;
|
赋值运算符结合性默认是由右向左: 上面的赋值可以认为是: w = (x = (y = (z = "Hello")));
等价的函数形式: w.operator=(x.operator=(y.operator=(z.operator=("Hello"))));
w.operator=, x.operator=和y.operator=的参数是前一个operator=调用的返回值; 所以operator=的返回值必须作为一个输入参数被函数本身接受;
缺省版本的operator=的形式: C& C::operator=(const C&);
一般情况下, operator=输入和返回的都是类对象的引用, 有时候需要重载operator=使它接受不同类型的参数;
e.g. string
1
2
|
string& operator=(
const
string& rhs);
// 将一个 string 赋给一个string
string& operator=(
const
char
*rhs);
// 将一个 char*赋给一个string
|
>即使是重载, 返回类型也要是类的对象的引用;
Note C++dev 经常犯的错误是将operator=返回void, 这样妨碍了连续(链式)赋值操作;
另一个常犯的错误是让operator=返回const对象的引用:
1
2
3
4
5
6
|
class
Widget {
public
:
...
const
Widget& operator=(
const
Widget& rhs);
...
};
|
>这样做通常是为了防止程序以下的无意义操作:
1
2
3
|
Widget w1, w2, w3;
...
(w1 = w2) = w3;
// w2 赋给w1, 然后w3 赋给其结果 (给operator=一个const 返回值 就使这个语句不能通过编译)
|
但是对于固定类型, 这样操作也是可以的; 所以没必要改变设定, 和固定类型的常规做法不兼容;
1
2
3
|
int
i1, i2, i3;
...
(i1 = i2) = i3;
// 合法! i2 赋给i1 然后 i3 赋给i1!
|
缺省形式定义的赋值运算符里, 对象返回值有两个候选, 1)赋值语句左边的对象(this指针指向的对象) 2) 赋值语句右边的对象(参数表中被命名的对象);
1
2
3
4
5
6
7
8
9
|