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

c++ Effective c++ 条款5

class MyClass {
public:MyClass(int& ref, const int c_val) : myRef(ref), myConstVal(c_val) {}// 明确删除拷贝操作MyClass(const MyClass&) = delete;MyClass& operator=(const MyClass&) = delete;private:int& myRef;       // 引用成员const int myConstVal; // const成员
};

注意资源管理陷阱


1. 赋值运算符的调用条件

赋值运算符 operator= 的语义是:将右侧对象的内容复制到左侧已存在的对象中。因此:

  • 左侧对象必须已经存在(已构造完成)。
  • 如果左侧对象尚未构造,C++ 会调用 拷贝构造函数 来初始化左侧对象。

2. 示例对比

场景 1:调用赋值运算符
Derived md;      // md 已经存在
md = bd;         // ✅ 调用赋值运算符 Derived::operator=
  • 解释md 是一个已经构造的对象,此时 md = bd; 会调用 Derived::operator=
场景 2:调用拷贝构造函数
Derived md = bd; // ❌ 调用拷贝构造函数 Derived::Derived(const Derived&)
  • 解释md 是一个新对象,尚未构造,因此 C++ 会调用 拷贝构造函数,而非赋值运算符。

3. 为什么 Derived md = bd; 调用的是拷贝构造函数?

C++ 的语法规则规定:

  • T a = b; 等价于 T a(b);(即调用拷贝构造函数),而不是 a = b;
  • 因此,Derived md = bd; 实际上是初始化语句,触发的是 拷贝构造函数

4. 如何显式触发赋值运算符?

要调用赋值运算符,必须确保左侧对象已经存在。例如:

Derived md;      // md 已构造
md = bd;         // ✅ 调用赋值运算符

5. 总结:关键区别

操作调用函数左侧对象是否存在?
Derived md = bd;拷贝构造函数❌ 不存在(初始化)
Derived md; md = bd;赋值运算符✅ 存在(已构造)

6. 参考知识库

  • 知识库 [1] 的说明

    赋值运算符不会创建新对象,而是操作左侧已有对象。 左侧对象必须已经存在,赋值运算符不会重新创建它。

  • 知识库 [10] 的说明

    赋值操作和初始化操作都会导致对象被复制。赋值是将一个对象的值分配给另一个对象,而初始化是在声明新对象时进行的。


7. 常见陷阱

  • 误认为 a = b; 一定调用赋值运算符:如果 a 是新对象,a = b; 会调用赋值运算符;但如果 a 是初始化语句的一部分(如 T a = b;),则调用拷贝构造函数。
  • 调试建议:在 operator= 中添加日志(如 std::cout),观察何时被调用。

通过理解这一规则,你可以避免混淆拷贝构造和赋值运算符的调用场景,编写更健壮的 C++ 代码。

http://www.xdnf.cn/news/1407439.html

相关文章:

  • 机器学习之线性回归
  • 数据结构02:排序算法
  • PyQt5 进度条详细示例与性能优化
  • 电商系统的分布式事务调优
  • Knit-易用的prompt管理和调试工具
  • 第六章:透明度-Transparency《Unity Shaders and Effets Cookbook》
  • io进程线程;标准IO;0831
  • 【嵌入式】【调用函数图】手动绘制函数调用状态机
  • 【优先算法--前缀和】
  • 3DES加解密的算法Java Python Golang
  • CVPR上的多模态检索+视频理解,LLM助力提效翻倍
  • 8.1【Q】VMware相关
  • 吴恩达机器学习作业十一:异常检测
  • 大模型——利用RAG构建智能问答平台实战
  • 在Ubuntu服务器上安装KingbaseES V009R002C012(Orable兼容版)数据库过程详细记录
  • Qwen3_moe模型代码解析
  • FreeRTOS实战:任务创建与调度详解
  • 【MySQL自学】SQL语法全解(上篇)
  • 【PS实战】逐步打造静物的艺术色调(大学作业)
  • 从零开始搭建使用 TDengine:新用户快速上手指南
  • windows docker 中的mysql 无法被外部浏览器访问如何解决
  • 自动驾驶中的传感器技术37——Lidar(12)
  • Ansible 临时命令与常用模块实操指南
  • 【人工智能99问】LLaMA中的RoPE是什么?(35/99)
  • Paimon——官网阅读:Spark 引擎
  • Spark内存管理
  • Nginx 502 Bad Gateway:从 upstream 日志到 FastCGI 超时复盘
  • 腾讯浑元最新技术:具有表征对齐的多模态扩散,用于高保真拟音音频生成
  • 【嵌入式DIY实例】-空中鼠标
  • LeetCode算法日记 - Day 27: 计算右侧小于当前元素的个数、翻转对