You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重载赋值运算符时返回*this的必要性、原理及非链式场景必要性咨询

关于重载赋值运算符返回*this的那些事儿

嘿,这个问题问得特别接地气——不少刚摸C++运算符重载的朋友都会在这儿犯嘀咕,我来给你拆解清楚。

先搞懂return *this的工作机制

首先得明确:在类的成员函数里,this是指向当前调用该函数的对象的指针,而*this就是这个对象本身的左值(可以被修改的对象实例)。当我们在赋值运算符里return *this时,返回的是当前对象的左值引用——简单说就是,这个返回值直接绑定到已经完成赋值操作的对象上,不是副本,就是对象本身。

举个直观的代码例子:

class Num {
private:
    int num;
public:
    Num(int n = 0) : num(n) {}
    
    Num& operator=(const Num& other) {
        // 先做自赋值检查(避免不必要的操作,比如内存重复释放)
        if (this != &other) {
            num = other.num;
        }
        return *this; // 返回当前对象的引用
    }
    
    int getNum() const { return num; }
};

当你执行c = a时,调用的是c.operator=(a),函数里把a的num赋值给c的num,然后返回c的引用——也就是说,c = a这个表达式的结果就是c本身,不是新创建的Num对象。

链式赋值的核心逻辑

现在看你提到的b = d = c = a,C++里赋值运算符是右结合的,所以这个语句会从右往左拆解:

  1. 先执行c = a,返回c的引用;
  2. 接着执行d = (c = a的结果),也就是d = c,返回d的引用;
  3. 最后执行b = (d = c的结果),也就是b = d,返回b的引用。

如果赋值运算符不返回*this(比如返回void),那第一步c = a的结果是void,第二步d = void就会直接编译报错——因为void类型不能作为赋值运算符的右操作数。这就是返回*this支持链式赋值的根本原因。

不用链式操作,还要返回*this吗?

答案是:非常建议返回,哪怕你现在用不上链式赋值。原因有三个:

  • 遵循C++的惯例:标准库中所有的类(比如std::string、std::vector)的赋值运算符都是返回左值引用的,保持一致的行为能让其他开发者更容易理解你的代码,也避免违反用户的直觉。
  • 兼容潜在的使用场景:你现在不用链式赋值,不代表以后或者其他使用你这个类的开发者不用。如果突然需要写if (a = b)这种(虽然有人觉得这种写法不优雅,但确实是合法的),返回void会直接报错,而返回*this就能正常工作(因为可以判断对象的状态)。
  • 和默认行为对齐:编译器自动生成的默认赋值运算符,也是返回*this的。自定义重载时保持一致,能避免出现奇怪的行为差异。

总结一下

return *this本质是返回当前被赋值的对象的左值引用,它不仅支撑了链式赋值的需求,更重要的是符合C++的设计惯例和默认行为。哪怕你暂时用不上链式操作,也最好坚持返回*this——这是一个低成本但收益很高的编码习惯。

内容的提问来源于stack exchange,提问作者maufcost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:23:45