Effective C++读书笔记之令operator= 返回一个reference to *this

本文详细解释了C++中赋值操作的连锁形式及其实现原理,包括如何通过返回引用来自定义类的赋值操作符,以支持类似内置类型的赋值行为。

 关于赋值,有趣的是你可以把它们写成连锁形式:
 int x,y,z;
 x = y = z = 15;   //赋值连锁形式
 赋值采用右结合律,所以上述连锁赋值被解析为:
 x = (y = (z = 15));
 这里15先被赋值给z,然后其结果(更新后的z)再被赋值给y,然后其结果(更新后的y)再被赋值给x。
 
 为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参。这是你为classes实现赋值操作符时应该遵循的
协议。
 class Widget {
 public:
  ....
  Widget& operator=(const Widget& rhs)  //返回类型是个reference指向当前对象
  {
   ...
   return *this;                 //返回左侧对象
  }
  ....
 };
 这个协议不仅适用于以上的标准值形式,也适用于所有赋值相关运算,例如:operator+= operator*=等等。
 这只是个协议,并无强制性的,如果不遵循它,代码一样可通过编译。但是这份协议被所有内置类型和标准库提供的类型如string,vector等共同遵守。因此你最好也遵守。
 总结:令赋值(assignment)操作符返回一个reference to *this

<think> 首先,用户的问题是关于运算符重载中operator=返回*this的原因。用户提供了几个引用,我应该基于这些引用来构建回答。记住系统级指:使用$...$表示行内数学表达式,独立公式用$$...$$,确保LaTeX语法正确,用中文回答,生成相关问题,并在引用的段落末尾自然地添加引用标识。 关键点从引用中提取: - 引用[1]提到,operator=通常应该返回类对象的引用(如string&),以支持链式赋值(如a = b = c)。它还指出有时operator=可以重载接受不同类型的参数。 - 引用[2]讨论了返回*this vs. rhs的争论,强调返回*this是为了处理临时对象和避免语法问题。它提到如果返回rhs,可能会出错,特别是对于临时对象。 - 引用[3]解释了返回引用是为了避免不必要的拷贝构造函数调用。它举例说明即使返回对象也能工作,但会导致额外的拷贝操作,效率低下。 核心原因: 1. **支持链式赋值**:如a = b = c,这要求赋值操作符返回左值,可以被后续赋值使用。返回引用避免创建临时对象。 2. **效率**返回引用而不是对象,避免了拷贝构造函数的调用,提高性能,尤其当对象较大时。 3. **一致性**返回*this引用是C++中的惯例,与内置类型的行为一致(如int的赋值返回引用)。 从引用[3],即使返回对象也能工作,但会导致额外的拷贝: - b = c 创建一个临时对象(通过拷贝构造函数)。 - 然后a = 这个临时对象,又创建另一个临时对象。 - 如果operator=返回引用,这些拷贝就被避免了。 回答结构: - 清晰、逐步解释原因。 - 使用中文。 - 引用末尾添加标识。 - 生成相关问题。 结构化回答: 1. **引入**:简述operator=返回*this的原因。 2. **详细解释**: - 支持链式赋值:解释为什么需要返回左值引用。 - 效率:避免不必要的拷贝。 - 语法一致性:与标准库和内置类型一致。 3. **示例**:提供代码示例来展示。 4. **结论**:总结要点。 5. **生成相关问题**:附加部分。 代码示例:使用简单的类来演示。确保格式正确。 生成相关问题:基于主题,提出相关问题。 引用标识: - 在解释中,自然地添加[^1], [^2], [^3]到相关部分。 最终输出: - 回答部分。 - §§相关问题§§部分。 </think> ### 运算符重载中operator=返回*this的原因 在C++中,重载赋值运算符`operator=`时返回`*this`(即返回当前对象的引用)是一种常见的约定和最佳实践。这基于以下几个关键原因,我将结合引用内容逐步解释。 1. **支持链式赋值操作**: 赋值运算符返回`*this`的引用(如`ClassName& operator=(const ClassName& rhs)`)允许实现链式赋值表达式,例如`a = b = c`。这种语法被解析为`a = (b = c)`: - 如果`operator=`返回引用(如`ClassName&`),则`b = c`返回`b`本身的引用(左值),后续`a = ...`可以直接使用这个引用,避免创建临时对象。 - 如果不返回引用(如返回对象),则`b = c`会生成一个临时对象(通过拷贝构造函数),后续赋值会再次调用拷贝构造函数,效率较低[^3]。 2. **提高效率和避免不必要的开销**返回引用(`*this`)避免了不必要的对象拷贝操作: - 当`operator=`返回对象时(如`Test operator=(const Test& p)`),每次赋值都会调用拷贝构造函数来创建临时对象。对于大型对象,这可能导致性能瓶颈。 - 返回引用则直接操作原对象,不需要额外拷贝,这与内置类型(如`int`)的赋值行为一致,提升了代码效率[^3][^2]。 例如: ```cpp class String { public: String& operator=(const String& rhs) { // 赋值逻辑... return *this; // 返回当前对象的引用 } }; ``` 如果改为`String operator=(const String& rhs)`,那么在`str1 = str2 = str3`中,会多出两次临时对象的拷贝构造。 3. **语法一致性和兼容性**: - **与内置类型和标准库一致**:内置类型(如`int`)的赋值返回左值引用,标准库(如`std::string`)也遵循此规则。这确保了用户自定义类型的行为可预测,便于与其他代码交互[^1][^2]。 - **处理临时对象和常数**:如果尝试返回右值(如`return rhs;`),但`rhs`可能是`const`临时对象(例如`x = "hello";`),会导致编译错误。返回`*this`则安全地引用当前对象,避免语法问题[^2]。 4. **避免潜在错误**返回`*this`确保了赋值表达式的左侧始终是有效对象。如果返回右侧对象(如`return rhs;`),会破坏对象的封装性,可能导致意外行为或错误[^2]。引用[3]提到,即使返回对象也能实现链式赋值,但牺牲了性能。 总之,返回`*this`的引用是C++中的惯例,它确保了链式赋值的高效性、语法简洁性和与语言标准的一致性。Effective C++中也强调这一原则,以优化资源管理和性能[^1][^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值