返回当前对象副本的正确写法是 return *this;,它调用拷贝或移动构造函数生成独立临时对象,要求返回类型为类类型且类具备可用拷贝构造函数。

返回当前对象副本的正确写法是 return *this;
成员函数要返回当前对象的副本,最直接的方式就是用解引用 this 指针:return *this;。这会调用类的拷贝构造函数(或移动构造函数,如果满足条件且已定义),生成一个新对象并返回。
注意:这不是返回引用,也不是返回指针,而是返回一个独立的、可被移动或拷贝的临时对象。
- 必须确保类有可用的拷贝构造函数(编译器默认生成的通常够用;若禁用了
= delete或未定义,则编译失败) - 若类含指针成员且需深拷贝,必须自定义拷贝构造函数和赋值运算符,否则
*this返回的是浅拷贝副本 - 返回类型必须与当前类一致(或其 const 限定版本),不能是
void或其他类型 - 不建议返回
this(指针)或*this的引用(T&),除非明确想提供链式调用且不产生副本
常见错误:误写成 return this; 或 return &*this;
return this; 返回的是 MyClass* 类型指针,与期望返回对象副本的语义完全不符,编译会报错(类型不匹配)。
return &*this; 等价于 return this;,仍是返回指针;而 return *&this; 是语法错误(& 不能作用于右值 *this,除非 *this 是左值引用)。
立即学习“C++免费学习笔记(深入)”;
典型错误现象:
error: cannot convert 'MyClass*' to 'MyClass' in return
- 看到这个错误,第一反应应检查是否误写了
return this; - 若函数声明返回
MyClass,就绝不能返回this或取地址表达式 - VS 和 GCC 都会在此处给出清晰类型不匹配提示,别忽略它
什么时候该用 return *this;?典型场景是支持链式调用的非 const 成员函数
比如实现流式接口的 setter:
class Config {
public:
Config& set_port(int p) { port = p; return *this; } // 返回引用,支持链式
Config with_host(std::string h) { host = std::move(h); return *this; } // 返回副本
};
关键区别:
-
set_port返回Config&→ 修改原对象,返回自身引用,效率高 -
with_host返回Config(即return *this;)→ 不修改原对象,返回新副本,适合函数式风格 - 后者常用于 immutable 接口设计,或避免意外修改原始实例
性能影响:每次 return *this; 都触发一次拷贝(或移动)。若对象较大且频繁调用,要考虑是否真需要副本,或改用 const 引用参数 + 工厂函数替代。
移动语义下 return *this; 会自动触发移动吗?
不会自动移动 —— *this 是左值(即使在右值引用成员函数中,this 指针本身仍是左值),所以 return *this; 默认调用拷贝构造函数。
若想强制移动,得显式转换:
return std::move(*this); // 在 && 重载函数中才合理
- 仅在成员函数被声明为
MyClass&& func() &&(即右值引用限定)时,std::move(*this)才有意义 - 普通
&限定函数里写std::move(*this)可能破坏原对象,且无实际收益(拷贝省不了) - 编译器 RVO/NRVO 通常能优化掉拷贝,但不能依赖;移动语义不是万能补丁
真正容易被忽略的是:返回副本看似简单,但一旦类里有资源管理逻辑(文件句柄、内存池、锁等),拷贝行为是否安全、是否符合设计意图,比语法正确性更重要。


















