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

第5章 构造、析构、拷贝语义学3:对象复制语意学

🍉 重点:编译器生成构造函数的四种情况,如何避免copy constructor在子类多个调用

当我们指定一个class object给另一个class object时,通常有三种选择:

  1. 什么都不做,实施默认的行为。

  2. 提供一个explicit copy assignment operator。

  3. 显式地拒绝指定一个class object给另一个class object,声明为private(并且此时不同函数的定义,一旦某个member function或friend企图影响一份拷贝,程序链接时就会失败)。

利用Point class来帮助讨论:

class Point {
public:
    Point(float x = 0.0, float y = 0.0);
private:
    float _x, _y;
};

如果不对class point提供copy assignment operator,光是依赖默认的memberwise copy,编译器不会产生出一个实例,因为此class已经有了bitwise copy语意,所以implicit copy assignment operator被视为毫无用处,根本不会合成出来。

一个class对于默认的copy assignment operator,在以下情况下,不会表现出bitwise copy语意

  • 当class内含一个class object,而其class有个copy assignment operator时

  • 当一个class的base class有个copy assignment operator是

  • 当一个class声明了任何virtual function(一定不要拷贝右端class object的vptr地址,因为他可能是一个derived class object)时

  • 当一个class继承自一个virtual base class(不论base class有没有copy operator)时

如果没有为Point3d设定一个copy assignment operator,编译器就会为其合成一个:

inline Point3d&
Point3d::operator=(point3d* this, const Point3d& p) {
    this->Point::operator=(p);  //base class operator=
    _z = p._z;  //memberwise copy
    return *this;
}

copy assignment operator缺乏一个member assignment list,类似于成员初值列,比如

inline Point3d&
Point3d::operator=(const Point3d& p)
    : Point(p), _z(p._z) { }    //这是不支持的,只能写成上面合成的形式

缺少 member assignment list,编译器一般就没有办法压抑上层 base class 的 copy operator 被调用。还是考虑之前的继承体系,类 Vertex 虚拟自 Point ,并且从 Point3d 和 Vertex 派生出Vertex3d。则copy operator 如下:

inline Vertex&
Vertex operator=(const Vertex& v) {
    this->Point::operator=(v);
    _next = v._next;
    return *this;
}
inline Vertex3d&
Vertex operator=(const Vertex3d& v) {
    this->Point::operator=(v);
    this->Point3d::operator=(v);
    this->Vertex::operator=(v);
    return *this;
}

编译器如何在 Point3d 和 Vertex 的 copy assignment operator 压制 Point 的 copy assignment operator呢?constructor 中的解决办法是添加一个额外的参数 __most_derived。解决办法是:为copy assignment operator 提供分发函数(split functions)以支持这个 class 称为 most-derived class或者成为中间的 base class。

尽可能不要允许一个 virtual base class 的拷贝操作,更进一步,不要在任何 virtual base class 中声明数据

相关文章:

  • 高频面试题(含笔试高频算法整理)基本总结回顾24
  • 【ElasticSearch】学习笔记
  • 零基础上手Python数据分析 (3):Python核心语法快速入门 (下) - 程序流程控制、函数与模块
  • 用ST7789屏幕导致负片(反色)的问题
  • 基于DeepSeek R1的检验检查超声影像综合预约排班和路径最优化研究
  • yolo环境 pytorch环境配置 CUDA安装
  • Google最新生图模型Gemini-2.0-Flash-Exp免费用
  • 大华SDK协议在智联视频超融合平台中的接入方法
  • lws-minimal-ws-server前端分析
  • YOLO11 使用入门
  • Qt常用控件之Layout总篇
  • Python(学习一)
  • Mac 上编译 Ragflow
  • Manus 技术探索 - 使用 gVisor 在沙箱内运行 Ubuntu 容器并通过远程浏览器访问
  • 【A2DP】深入解读A2DP中通用访问配置文件(GAP)的互操作性要求
  • python速通小笔记
  • 关于单一职责原则
  • 星型组网模块的两种交互方式优缺点解析
  • 【国际研讨会】2025年3-5月通信、算法、电气工程、自动化等领域国际学术会议征稿开启!大型学术盛宴!
  • console.log(MyEnum[0])和console.log(MyEnum.A)区别
  • 贵州赤水丹霞大瀑布附近山体塌方车辆被埋,景区:无伤亡,道路已恢复
  • 以色列消防部门:已控制住耶路撒冷山火
  • 5月人文社科中文原创好书榜|巫蛊:中国文化的历史暗流
  • 购车补贴、“谷子”消费、特色产品,这些活动亮相五五购物节
  • 五一假期,这些短剧值得一刷
  • 伊朗外长:伊美第四轮间接谈判将于5月3日举行