C++中重载assignment operator设为void返回类型有何特定优势?
我正在学习面向对象设计课程,指定教材是丁格尔(Dingle)2021年所著的《Object-oriented design choices》。在学习Move Semantics章节时,我遇到一个讨论深拷贝与浅拷贝的示例,其中的赋值运算符定义让我困惑。
该章节前半部分讲解拷贝语义,包括拷贝构造函数和重载赋值运算符,书中给出的简化示例如下:
class goodMM { private: int* m_heapData; int m_size; void copyData(const goodMM& other) { // ... } public: goodMM(int size) { // ... } ~goodMM() { // ... } goodMM(const goodMM& other) { // ... } void operator=(const goodMM& other) { // ... } };
我所学的知识是,operator=应始终返回T&类型的引用,这样可以支持链式赋值(如a = b = c),同时避免不必要的拷贝操作提升效率。我查过相关资料,也确认标准做法是返回引用。想请教:这个示例场景下,把operator=声明为void返回类型是否有特定益处或优势?
回答:
首先要明确:你所学的知识完全正确,C++中赋值运算符返回T&是常规惯例,也是标准库、内置类型遵循的行为,支持链式赋值且符合用户预期。
至于示例中用void返回,主要有两种可能:
教学简化需求:这个示例的核心是展示深拷贝/浅拷贝的逻辑框架,重点在
copyData的调用、拷贝构造与赋值运算符的结构。教材作者可能为了避免初学者分心,故意省略了返回值的细节——毕竟返回引用需要额外写return *this;,而这不是当前章节要讲解的重点。小众的设计选择:极少数场景下,开发者会用
void返回禁止链式赋值。比如某些状态敏感的类,设计上希望用户每次只执行一次赋值操作,避免a = b = c这种写法可能带来的逻辑混淆(比如如果类的赋值有副作用,链式赋值的执行顺序可能不符合直觉)。但这属于非常特殊的设计,完全不符合C++的通用惯例,实际工程中几乎不会这么用。
需要强调的是:void返回的赋值运算符没有任何性能优势,反而会丢失链式赋值的便利性,还会违反用户对C++赋值操作的默认预期。所以这个示例里的写法更可能是教学上的简化,而非推荐的实践方案。
内容的提问来源于stack exchange,提问作者i_hate_F_sharp

