C++赋值运算符声明中“=”前的“&”作用是什么?
关于赋值运算符声明中“=”前“&”的作用
嘿,这个细节抓得真准!你看到的那个紧跟在函数参数列表后面的&,是C++11引入的引用限定符(ref-qualifier),专门用来限定成员函数能被哪种类型的对象调用——左值还是右值。
先快速梳理下左值和右值的核心区别:
- 左值是能取地址、可反复使用的对象(比如
C obj;里的obj); - 右值是临时对象或无法被赋值的临时值(比如
C()创建的匿名临时对象)。
这个&的具体作用
当成员函数的参数列表后面加上&,意味着这个函数只能被左值对象调用;如果换成&&,则只能被右值对象调用。
拿你给出的例子拆解来看:
C& operator=(const C&) & = default;:这个拷贝赋值运算符加了&限定,所以只有左值的C对象才能调用它。比如C a; C b; a = b;完全没问题,因为a是左值;但如果写C() = b;就会直接编译报错——因为C()是临时右值,没有资格调用这个左值限定的赋值运算符。- 同理,如果是
C& operator=(C&&) && = default;(右值限定的移动赋值运算符),它只能被右值对象调用。比如C a; a = C();里的C()是右值,可以正常调用;而左值对象如果想调用它,必须先转成右值(比如std::move(b)),本质上是为了明确函数的专属调用场景。
为什么要加这个限定?
最核心的原因是避免无意义的操作:给临时右值对象赋值完全没有价值——赋值完成后,临时对象马上就会被销毁,你根本没法用到赋值后的结果。用引用限定符可以在编译阶段就阻止这种冗余代码,同时也能让编译器更精准地优化,或者明确函数的使用边界。
对比无限定的情况:如果成员函数没加&或&&,它既能被左值调用,也能被右值调用,这在很多场景下是不必要的(比如默认生成的赋值运算符就允许给右值赋值,但多数时候这是多余的)。
实际代码示例
#include <iostream> class C { public: C() = default; // 左值限定的拷贝赋值运算符 C& operator=(const C&) & = default; }; int main() { C a, b; a = b; // 正常编译,a是左值 // C() = b; // 编译错误!临时右值无法调用左值限定的operator= return 0; }
内容的提问来源于stack exchange,提问作者Sumit Jha
相关产品推荐
相关产品推荐

