本文是 Inside The C++ Object Model's Chapter 2  的部分读书笔记。

有三种情况,需要拷贝构造函数:

1)object直接为另外一个object的初始值

2)object作为函数以值传递的参数

3) object以函数返回值形式返回

如果class没有提供一个explicit copy constructor时,编译器会以default memberwise initialization,也就是把每一个内建的或者派生的data member的值,从某个object直接拷贝到另外一个object上,对于member class object,以递归的方式施行memberwise initialization。

编译器并不会生成trivial的copy constructor,除非是bitwise copy semantics,以下四种情况就是非bitwise copy semantics:

1)class的某个member object声明有一个copy constructor时,这个copy constructor不会是被设计者声明的,或者是被编译器合成的

2)class继承自的base class含有copy constructor时

3)class含有virtual functions

4)class的base class是virtual时

编译器需要合成copy constructor,并且调用member object或者base class的copy constructor。

对于virtual function或者virtual inheritance,编译器需要为每一个object设计好vptr以便在runtime获取到正确的virtual function table。因为vptr处理不好有可能发生对象的sliced,导致出现blow up。

总结:

如果class是bitwise copy semantics,那么编译器不会合成copy constructor,只是按照default memberwise initialization copy source object到destination object。否则,编译器将合成copy constructor,以调用member object或者base class的copy constructor或者使得vptr设置好,使得在runtime可以使virtual base class或者base
class可以正确访问virtual functions。

注意,本文只是说明编译器在copy constructor上为我们做了什么,并不是编译器合成的copy constructor就是安全可用的。这里需要和deep copy(深拷贝)/shallow copy(浅拷贝)加以区别。和编译器是否为我们合成default constructor一样,它只是完成自己的职责,并不会为non class member object and non-static members 初始化。 如果需要deep copy,设计者必须explicit declare copy
constructor。否则即使编译器合成了,也会使得程序出现undefined behaviors。

C++对象模型(二):The Semantics of Copy Constructors(拷贝构造函数之编译背后的行为)的更多相关文章

  1. The Semantics of Constructors(拷贝构造函数之编译背后的行为)

    本文是 Inside The C++ Object Model's Chapter 2  的部分读书笔记. 有三种情况,需要拷贝构造函数: 1)object直接为另外一个object的初始值 2)ob ...

  2. 【C++对象模型】构造函数语意学之二 拷贝构造函数

    关于默认拷贝构造函数,有一点和默认构造函数类似,就是编译器只有在[需要的时候]才去合成默认的拷贝构造函数. 在什么时候才是[需要的时候]呢? 也就是类不展现[bitwise copy semantic ...

  3. 深入探索C++对象模型(二)

    构造函数语义学(The Semantics of Constructors) Default Constructor的构造操作 对于class X,如果没有任何user-declared constr ...

  4. C++对象模型的那些事儿之四:拷贝构造函数

    前言 对于一个没有实例化的空类,编译器不会给它默认生成任何函数,当实例化一个空类后,编译器会根据需要生成相应的函数.这类函数包括一下几个: 构造函数 拷贝构造函数 析构函数 赋值运算符 在上一篇博文C ...

  5. copy深浅拷贝

    我们在很多方法里都看到copy()方法,这是对变量的复制,赋值,下面来看一下实例: 复制方法调用的是copy模块中的方法: import copy copy.copy()         #前拷贝 c ...

  6. 包,logging日志模块,copy深浅拷贝

    一 包 package 包就是一个包含了 __init__.py文件的文件夹 包是模块的一种表现形式,包即模块 首次导入包: 先创建一个执行文件的名称空间 1.创建包下面的__init__.py文件的 ...

  7. 使用copy来拷贝对象

    拷贝对象 您通过将 copy 消息发送给对象,以制作对象的副本. NSArray *myArray = [yourArray copy]; 要拷贝,接收对象的类必须遵守 NSCopying 协议.如果 ...

  8. 从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数

    一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化段 普通计算段 (一).对象成员及其初始化  C++ Code  1 2 3 4 5 6 7 8 9 1 ...

  9. (C++)关于拷贝构造函数 Copy Constructor

    题目: In which of the following scenarios is a Copy Constructor called or invoked? A.    When no conve ...

随机推荐

  1. Struts2 转换器

    转换器 从一个 HTML 表单到一个 Action 对象,类型转换是从字符串到非字符串 Http 没有 "类型" 的概念,每一项表单的输入只可能是一个字符串或一个字符串数组,在服务 ...

  2. Numpy函数学习--genfromtxt函数

    genfromtxt函数 今天学习时遇到了genfromtxt函数 world_alcohol = numpy.genfromtxt("world_alcohol.txt",del ...

  3. python脚本文件传参并通过token登录后爬取数据实例

    from bs4 import BeautifulSoup import requests import sys class Zabbix(object): def __init__(self, he ...

  4. 导出和导入Docker容器

    导出容器 如果要导出本地某个容器,可以使用 docker export 命令. $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATU ...

  5. ERROR: Cannot change version of project facet Dynamic Web Module to 3.0?

    Issue: When you create web app in eclipse with maven configuration, you may get following error. Can ...

  6. UILabel 调整行间距

    /* 调整行间距 */ + (void)adjustLineSpacingOfLabel:(UILabel *)label to:(CGFloat)lineSpacing { NSString *te ...

  7. EBS开发性能优化之查找需要优化的程序

    1.登陆数据库LINUX环境 使用 top 命令查看进程状况 [oratest@ebsdb~]$top top - 15:58:59 up 8 days, 22:04,  1 user,  load ...

  8. PGM:无向图模型:马尔可夫网

    http://blog.csdn.net/pipisorry/article/details/52489321 马尔可夫网 马尔可夫网在计算机视觉领域通常称为马尔可夫随机场(Markov random ...

  9. JVM基础知识GC

    在网上看到一篇很不错的讲解JVM GC的文章,看完之后觉得可以留着以后多看几遍便转载了下来.但是找了半天也没有找到原作者地址.抱歉不能标明原文地址了.以下是文章内容. 几年前写过一篇关于JVM调优的文 ...

  10. Android 读取清单文件<meta-data>元素的数据

    添加属性 <application -- > <meta-data android:value="Channel_0" android:name="UM ...