当前位置: 首页 > news >正文

Effective C++ 条款10:令operator=返回一个reference to *this

Effective C++ 条款10:令operator=返回一个reference to *this


核心思想赋值操作符(operator=)应始终返回当前对象的引用(*this),以实现连锁赋值并保持与内置类型一致的语义。

⚠️ 1. 问题场景:违反连锁赋值语义
class Widget {
public:void operator=(const Widget& rhs) { // 错误:返回voidvalue = rhs.value;}
private:int value;
};int main() {Widget a, b, c;a = b = c; // 错误:void类型不能作为右值return 0;
}

结果

  • 编译错误:void 类型不能用于赋值操作
  • 破坏与内置类型(如int)一致的赋值语义

2. 解决方案:返回 *this 引用
(1) 标准赋值操作符实现(⭐️必须
class Widget {
public:Widget& operator=(const Widget& rhs) { // 返回当前对象引用if (this != &rhs) {               // 自赋值检查(条款11)value = rhs.value;}return *this; // 关键:返回 *this}
private:int value;
};
(2) 复合赋值操作符实现(+=, -=等)
Widget& operator+=(const Widget& rhs) {value += rhs.value;return *this; // 同样返回 *this
}// 使用:
Widget x, y, z;
x = y += z; // 支持连锁操作

🔍 3. 关键原则
场景操作原因
基本赋值 operator=必须返回 Widget&支持 a=b=c 连锁赋值
复合赋值 operator+=同样返回 Widget&保持与基本赋值一致的行为
避免返回 const Widget&返回非const引用允许 (a=b).doSomething() 链式调用
继承体系中的赋值操作符调用基类赋值操作符并返回自身引用确保基类部分正确赋值

⚠️ 4. 错误案例:返回临时对象
class Widget {
public:Widget operator=(const Widget& rhs) { // 错误:返回值而非引用return Widget(rhs.value);         // 返回临时对象副本}
};// 使用:
a = b = c; // 编译通过但行为错误:
// b=c 返回临时对象,a 被赋值为临时对象而非c

后果

  • 产生额外临时对象(性能损失)
  • a 最终获得 c 的副本,但 b 未被修改
  • 违反 “a=b” 应修改 b 的预期

💎 总结:赋值操作符三原则

  1. 返回 *this 引用
    所有赋值操作符必须返回当前对象的非const引用:

    class MyClass {
    public:MyClass& operator=(const MyClass& rhs) {// ... 赋值操作return *this;}
    };
    
  2. 保持连锁赋值语义
    确保支持 x=y=z 语法,行为等价于:

    y = z;
    x = y;
    
  3. 兼容内置类型行为
    赋值表达式结果应为左值(可继续被赋值):

    (a = b) = c; // 应合法:a被赋值为c
    
http://www.dtcms.com/a/303805.html

相关文章:

  • 渗透测试与漏洞扫描有什么区别?
  • napping靶机教程(超详细讲解)
  • Leetcode-3152 特殊数组 II
  • TCPDump实战手册:协议/端口/IP过滤与组合分析指南
  • 【Java面试题】面向对象
  • 站点到站点-主模式
  • 【C++基础】函数调用约定(x86/ARM 差异对比):面试高频考点与真题解析
  • 面试遇到的问题3
  • java String类
  • 打印机错误0x0000011B,0x00000709,0x00000BCD,修复工具下载。
  • ElasticSearch 的3种数据迁移方案
  • Nginx安装流程
  • Vue.js 指令系统完全指南:深入理解 v- 指令
  • 递归推理树(RR-Tree)系统:构建认知推理的骨架结构
  • 【C++】1. C++基础知识
  • 传媒行业视频制作:物理服务器租用是隐藏的效率引擎
  • 【Golang】Go语言Map数据类型
  • Qt 并行计算框架与应用
  • 【go】语言的匿名变量如何定义与使用
  • TDengine 中 TDgpt 异常检测的机器学习算法
  • spring data mongodb 入门使用手册
  • [Linux入门] Linux 部署本地 APT 仓库及 NFS 共享服务全攻略
  • Java -- String类-StringBuffer类-StringBuilder类
  • uniapp开发微信小程序(新旧版本对比:授权手机号登录、授权头像和昵称)
  • K-近邻算法(KNN算法)的K值的选取--交叉验证+网格搜索
  • 搭建专属AI聊天网站:NextChat + 蓝耘MaaS平台完整部署指南
  • 2025年7月技术问答第4期
  • 树形结构递归查询与嵌套结构转换:Flask + PostgreSQL 完整实现
  • 力扣面试150题--位1的个数
  • 【第四章自定义编辑器窗口_扩展默认的编辑器窗口_扩展Hierarchy窗口(7/11)】