前言

在三种情况下,会以一个 object 的内容作为另一个 class object 的初值:

  1. object明确初始化
class X{...};
X x;
X xx = x;
  1. object 被当作参数交与某个函数
extern void foo(X x);
void bar(){
X xx;
foo(xx);//作为第一个参数的初值(不明显的初始化)
}
  1. 函数返回值是一个 class object
X foo_bar(){
X xx;
...
return xx;
}

如果开发者已经明确定义了一个copy constructor 如下:

//copy constructor可以是多参数,其中有一个参数是其class type
X::X(const X& x);
Y::Y(const Y& y);

那么在大部分情况下,当 class object 以另一个同类实体作为初值时,上述 constructor 会被调用,这可能会导致一个暂时性 class object 的产生或程序代码发生改变(或二者都有)。

重新设定 Virtual Table 的指针

​ 编译期间的扩张操作(只要有一个class声明了一个或多个virtual function):

  • 增加一个 virtual function table(vtbl),内含每一个有作用的 virtual function 的地址。

  • 一个指向 virtual function table 的指针(vptr),安插在每个 class object 内。

    如果编译器对每个新产生的 class object 的 vptr 不能正确的设置初值,则会出错。因此,当编译器导入 vptr 到 class 中时,该 class 不再展现 bitwise semantics。而是合成一个 copy constructor 来使得 vptr 正确初始化,下面是个例子:

    class ZooAnimal{
    public:
    ZooAnimal();
    virtual ~ZooAnimal();
    virtual void animate();
    virtual void draw();
    private:
    ...//some data
    };
    class Bear : public ZooAnimal{
    public:
    Bear();
    void animate();
    void draw();
    private:
    ...//some data
    };

    ZooAnimal class object 以另一个 ZooAnimal class object 为初值,或 Bear class object 以另一个 Bear class object 为初值,都可以直接靠 bitwise copy semantics 完成。在这种情况下,vptr保持bitwise copy是安全的。

    当一个 base class object 以其 derived class object 内容作初始化操作时,其 vptr 也需要保证安全:

    Bear B;
    ZooAnimal Z = B;//sliced

    显然,Z的 vptr 不应该指向 Bear 的 vtbl,也就是说,Base class 被合成出来的copy constructor会明确设定 object 的 vptr 指向 Base Class 的 vtbl,而非从 rhs 处执行 bitwise copy。

构造函数语义学——Copy Constructor 的构造操作的更多相关文章

  1. Copy Constructor的构造操作

    Copy Constructor的构造操作 有三种情况,会以一个object的内容作为另一个class object的初值: 1.  对一个object做显式的初始化操作 class X{…}; X ...

  2. 构造函数语义学——Copy Constructor 篇

    构造函数语义学--Copy Constructor 篇 本文主要介绍<深度探索 C++对象模型>之<构造函数语义学>中的 Copy Constructor 构造函数的调用时机 ...

  3. 深度探索C++对象模型之第二章:构造函数语意学之Copy constructor的构造操作

    C++ Standard将copy constructor分为trivial 和nontrivial两种:只有nontrivial的实例才会被合成于程序之中.决定一个copy constructor是 ...

  4. 构造函数语义学——Default Constructor篇

    构造函数语义学--Default Constructor 篇 这一章原书主要分析了:编译器关于对象构造过程的干涉,即在对象构造这个过程中,编译器到底在背后做了什么 这一章的重点在于 default c ...

  5. Default Constructor的构造操作

    Default Constructor的构造操作 C++ Annotated Reference Manual书中的Section 12.1说过:default constructor 只有在编译器需 ...

  6. 深度探索C++对象模型之第二章:构造函数语意学之Default constructor的构造操作

    C++新手一般由两个常见的误解: 如果任何class没有定义默认构造函数(default constructor),编译器就会合成一个来. 编译器合成的的default constructor会显示的 ...

  7. C++ 类 复制构造函数 The Copy Constructor

    一.复制构造函数的定义 复制构造函数是一种特殊的构造函数,具有一般构造函数的所有特性.复制构造函数创建一个新的对象,作为另一个对象的拷贝.复制构造函数只含有一个形参,而且其形参为本类对象的引用.复制构 ...

  8. 构造函数语义学之Copy Constructor构建操作(2)

    二.详述条件 3 和 4 那么好,我又要问大家了,条件1 和 2比较容易理解.因为member object或 base class 含有copy constructor.那么member objec ...

  9. 构造函数语义学之Copy Constructor构建操作(1)

    一.Copy Constructor的构建操作 就像 default constructor 一样,如果class没有申明一个 copy constructor,就会隐含的声明或隐含的定义一个.生成的 ...

随机推荐

  1. uC/OS-III 时间管理(二)

    时间管理就是一种建立在时钟节拍上,对操作系统任务的运行实现时间上管理的一种系统内核机制. 常用以下五个函数: OSTimeDly() OSTimeDlyHMSM() OSTimeDlyResume() ...

  2. Kubernetes 系列(三):Kubernetes使用Traefik Ingress暴露服务

    一.Kubernetes 服务暴露介绍 从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务:到目前为止 kubernetes 总共有三种暴露 ...

  3. php-fpm启动,重启,退出

    首先确保php-fpm正常安装,运行命令php-fpm -t输出查看: ##确定php-fpm配置正常 [root@iz2vcf47jzvf8dxrapolf7z php7.-Oct-::] NOTI ...

  4. Salesforce学习之路-developer篇(三)利用Visualforce Page实现页面的动态刷新案例学习

    Visualforce是一个Web开发框架,允许开发人员构建可以在Lightning平台上本地托管的自定义用户界面.其框架包含:前端的界面设计,使用的类似于HTML的标记语言:以及后端的控制器,使用类 ...

  5. 校园网 虚拟机VMware Linux桥接模式 无法上网 问题

    只是解决常见虚拟机桥接模式 无法上网问题,基本的百度都有 基本知识 虚拟机有三种网络连接模式:桥接模式,net模式,仅主机 桥接模式:同一网段允许的话,相当于一个独立的物理主机,独立ip net模式: ...

  6. yii2 rules 规则

    required : 必须值验证属性 [['字段名'],required,'requiredValue'=>'必填值','message'=>'提示信息']; #说明:CRequiredV ...

  7. TouchListener PK OnTouchEvent + 多点触碰

    1.基于监听的TouchListener 代码示例: 实现效果图: 实现代码: main.xml <RelativeLayout xmlns:android="http://schem ...

  8. SDN网络IPv6组播机制支持实时视频业务海量用户扩展

    以 OpenFlow 技术为核心的软件定义网络(SDN)框架具有集中控制的功能能够自己感知网络拓扑的变化,在细粒度的路径选择.接入控制.负载均衡方面有着天然的优势,为 IPv6 组播功能的实现提供了好 ...

  9. NOIP2014联合权值

    无向连通图G有n个点,n-1条边.点从1到n依次编号,编号为i的点的权值为Wi  ,每条边的长度均为1.图上两点(u, v)的距离定义为u点到v点的最短距离.对于图G上的点对(u, v),若它们的距离 ...

  10. JVM垃圾回收算法详解

    前言 在JVM内存模型中会将堆内存划分新生代.老年代两个区域,两块区域的主要区别在于新生代存放存活时间较短的对象,老年代存放存活时间较久的对象,除了存活时间不同外,还有垃圾回收策略的不同,在JVM中中 ...