当前位置: 首页 > 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.dtcms.com/a/359694.html

相关文章:

  • Ubuntu24.04(Jazzy)从零开始实现环境配置和Gmapping建图
  • 北京博乐科技有限公司2025届程序技术类笔试题
  • 京东获取商品评论指南,实时关注用户反馈
  • 【秋招笔试】2025.08.30科大讯飞秋招笔试题
  • PetaLinux的JTAG启动
  • Linux/UNIX系统编程手册笔记:用户和组、进程凭证、时间以及系统限制和选项
  • 创维LB2004_安装软件教程
  • vscode克隆远程代码步骤
  • MSVC---编译器工具链
  • 基于GA遗传优化的双向LSTM融合多头注意力(BiLSTM-MATT)时间序列预测算法matlab仿真
  • 【秋招笔试】2025.08.29阿里云秋招笔试题
  • 拉长视频时长的两种方法
  • 2023年IEEE IOTJ SCI1区TOP,动态环境下无人机目标覆盖任务路径规划,深度解析+性能实测
  • 腾讯浑元最新技术:具有表征对齐的多模态扩散,用于高保真拟音音频生成
  • 免税商品优选购物商城系统|java技术开发
  • 计算机网络总览
  • join怎么用
  • 性能测试工具-Slow Query Log
  • C/C++ 高阶数据结构 —— 二叉搜索树(二叉排序树)
  • 安装Android Studio
  • DVWA靶场通关笔记-SQL Injection (Impossible级别)
  • 【LeetCode - 每日1题】解数独
  • Tomcat 中部署 Web 应用
  • [灵动微电子 MM32BIN560CN MM32SPIN0280]读懂电机MCU 模拟输入运放放大
  • LangChain Prompt管理核心:PromptTemplate与ChatPromptTemplate全解析
  • 旦旦的农场打卡计划
  • 合约服务架构-OOP 方式
  • Linux系统比较两个​​已排序文件​​的实用工具之comm
  • R3:适用于 .NET 的新一代响应式扩展库,事件订阅流
  • HarmonyOS 应用开发:基于API 12及以上的新特性与实践