C++ operator= 操作符重载返回值为什么是自身的引用?
1. 内置数据类型连续赋值
int a, b, c = 9;
a = b = c; // A
(a = (b = c)) // B
(a = b) = c; // C
- A 处基本类型连续赋值,其效果相当于 B 处,赋值顺序为 [c–>b --> a]
- C 处赋值,由于小括号优先级最高,因此赋值顺序为 [b–>a ; c–>a]
2. 如果 operator= 返回非自身引用
class Person{
public:
Person(int id):m_id}{id}{
}
Person operator=(const Person &p){
this->m_id = p.m_id;
return *this;
}
private:
int m_id = o;
};
Person p(1);
Person p2(2);
Person p3(3);
(p = p2) = p3; // A
如果 operator=
返回的是非自身引用,当前对象会调用【拷贝构造函数】生成一个临时对象作为返回值
,这种方式存在两个问题:
- 返回调用拷贝构造创建临时对象,浪费资源
- A 处代码,
p
最终还是等于p2
,这里因为p = p2
⇒ p.operator=(p2),而返回值是临时变量,此时p3
的值是赋值给了临时变量,故p
==p2
而不是p3
。此时,出现了歧义,故而返回非自身引用不妥。
3. operator= 返回自身引用
class Person{
public:
Person(int id):m_id}{id}{
}
Person& operator=(const Person &p){
this->m_id = p.m_id;
return *this;
}
private:
int m_id = o;
};
Person p(1);
Person p2(2);
Person p3(3);
(p = p2) = p3; // B
由于 operator=
返回的是自身的引用,故而完美解决上节中出现的两个问题:
- 返回自身引用,该过程避免了调用**【拷贝构造】生成临时变量**,自身引用的本质即
别名
- B 处代码,
p
最终还是等于p3
,这里因为p = p2
⇒p.operator=(p2)
,而返回值是p
的引用即自身的别名,此时p3
的值相当于赋值给了p
。