返回const引用的拷贝赋值运算符的用途与使用疑问
拷贝赋值运算符返回const引用的意图与用法解析
首先明确:执行a = b时,a完全不需要被声明为const对象。你混淆了「赋值表达式的结果类型」和「a本身的类型」——赋值运算符作用在非const的a上,会修改a的内部状态,只是它返回的是*this的const引用,意味着赋值表达式的结果是不可修改的,而非a变成了const。
这种写法的核心意图
最主要的目的是禁止无意义的链式赋值操作,比如开发者不小心写出(a = b) = c这类代码。
如果赋值运算符返回普通非const引用,(a = b) = c是合法的:它会先把b的值赋给a,接着把c的值赋给a(因为a = b返回的是a的引用),最终a的值是c。这种写法几乎都是笔误,没有实际业务意义,返回const引用就能让编译器直接报错,从语法层面杜绝这类错误。
实际使用场景示例
假设我们有这样的类:
class MyClass { private: int val; public: MyClass(int v = 0) : val(v) {} const MyClass& operator=(const MyClass& other) { if (this != &other) { val = other.val; } return *this; } void setVal(int v) { val = v; } int getVal() const { return val; } };
执行以下操作是完全合法的:
MyClass a, b(5), c(10); a = b; // 正常赋值,a的val变为5 a.setVal(20); // 赋值后依然可以修改a的状态
但如果尝试(a = b) = c,编译器会直接报错,因为a = b返回的是const引用,不能作为赋值操作的左值。
写法的取舍
这种写法属于「防御性编程」的一种,牺牲了极小的灵活性(几乎没人会需要把赋值结果当左值修改),换来了代码的严谨性,避免低级笔误。当然,C++标准库中的大部分类(比如std::string)的赋值运算符返回的是非const引用,允许链式赋值,这取决于类的设计目标——如果你的类需要严格避免这类误操作,就可以采用返回const引用的写法。
内容的提问来源于stack exchange,提问作者Amelio Vazquez-Reina
相关产品推荐
相关产品推荐

