赋值运算符重载返回值为何用Class&?返回值为Class时计数异常解析
关于C++赋值运算符返回类型的疑问解答
先贴出你给出的类代码:
class Class { public: int x; static int count; Class& operator=(const Class& c) { this->x = c.x; // 注意:这里漏了return *this; 标准赋值运算符必须返回自身的引用 } };
一、为啥赋值运算符要返回Class&而不是Class?
- 支持链式赋值:比如写
a = b = c;,这行代码实际是先算b = c,再把结果赋值给a。如果返回Class&,b = c返回的是b本身的引用,直接就能赋值给a;要是返回Class,b = c会生成一个临时对象,再把这个临时对象赋值给a,不仅多了对象创建销毁的额外开销,而且和int这类原生类型的链式赋值逻辑不一样,不符合直觉。 - 避免没必要的拷贝:返回
Class类型时,函数结束会把当前的*this拷贝成一个临时对象返回,这个拷贝过程会触发拷贝构造函数,对于大对象来说,这种额外拷贝的性能损耗很明显。 - 符合行业惯例:C++标准库所有类的赋值运算符都是返回自身引用,这么写能让你的代码和主流写法保持一致,别人读起来也更顺手。
二、返回Class时静态变量count为啥会增加?
你说“没调用构造函数但count仍增加”,其实是没注意到返回值的拷贝构造过程:
当赋值运算符返回Class类型时,函数执行完后,会把当前对象*this拷贝成一个临时对象作为返回值,这个过程一定会调用拷贝构造函数。如果你的count是在构造函数(包括拷贝构造)里做递增的(比如默认构造、拷贝构造里都写了count++),那这个临时对象的创建就会触发拷贝构造,直接导致count加1。
举个实际例子,假设你的类补充了构造函数:
Class() { count++; } Class(const Class&) { count++; }
当你执行a = b;且赋值运算符返回Class时,operator=内部完成赋值后,会调用拷贝构造函数生成临时对象返回,这一步就会让count加1——哪怕这个临时对象之后马上被销毁,count已经涨上去了。
但如果返回Class&,就不会生成任何临时对象,自然不会触发拷贝构造,count也就不会平白无故增加了。
内容的提问来源于stack exchange,提问作者decrepitude
相关产品推荐
相关产品推荐

