《深度探索c++对象模型》学习笔记 - 2 构造函数语义学

来源:互联网 发布:域名授权系统 作用 编辑:程序博客网 时间:2024/05/17 23:15

 

1.         全局对象的内存会被初始化为0,但是Local对象由于在stack中,所以不会被清0,而是随机的垃圾数据。

2.         Default constructor 的构建。如果没有用户定义的构造函数,则会有一个默认构造函数被implicitly构建出来,但这个构造函数是trivial constructor(没啥用处的)。如下四种情况下的类,编译器会构建nontrivial constructor出来(当然,如果该类有其他构造函数,却没有默认构造,则编译器会扩张每个构造函数而加入新的代码,却不生成新的构造函数):

a)    成员变量的类带有(不论是什么原因而带有的)默认构造函数。这时,编译器会扩张已经存在(或并不存在的)构造函数,插入代码来调用成员变量的构造函数。如果被调用的类(下同,基类等)没有默认构造函数,会报错。

b)    基类带有默认构造函数。这时,按照声明顺序依次调用基类的构造函数。

c)     新定义的或继承而得到虚函数。Vptr(每个对象)和vtbl(每个类)会给构造出来。

d)    有直接虚拟基类或继承链上有虚拟基类。

上述四种情况下,有implicit nontrivial constructor被构建,但他们只能符合编译器(而非程序)的要求。这四种情况之外,且没有声明任何constructor的类,可以说它有trivial constructor,但实际上它根本就不会被构建出来。

3.         Copy constructor 的构建。三种情况可以以一个对象的内容来构建另一个对象的初值:X x2 = x1; foo(x2); return x2;

a)    如果没有提供显式的copy构造,则用default memberwise initialization手法完成,即:copy成员的值而非深层对象。

b)    Bitwise copy(逐位copy)。对于基本类型和指针,会进行默认的shallow copy,而不进行调用构造函数这样的深度copy。这时,copy构造函数是trivial的,即编译器不会合成到程序中。

c)     类在下述四种情况下不具备Bitwise copy semantic,这时,nontrivial copy constructor会被构造出来:

Ø 成员变量的类带有(不论是何原因而有)拷贝构造函数。即:有“对象”成员,而非只有基本数据类型成员。

Ø 基类带有拷贝构造函数。

Ø 带有或继承而得到虚函数。重新设置vptr,并且,如果该对象是第一个对象的话还会构造vtbl

Ø 有直接虚拟基类或继承链上有虚拟基类。

d)    指针成员的copy会带来name aliasing的问题:多个指针指向同一个内存。

4.         成员初始化队列(Member Initialization ListMIL)。

a)    必须使用MIL的场合:1)引用类型成员;2const成员;3)基类构造函数有参数;4)成员变量构造函数有参数。

b)    MIL进行初始化会避免产生先初始化对象再赋值的问题,因为成员在进入构造函数的 { 之前必须已被构造完成。

c)     其成员的构造函数执行顺序与“成员变量在class定义中的声明顺序” 严格一致,而无论MIL中的顺序如何;换句话说,MIL中的代码可能会被编译器调整顺序。并且,MIL的代码在任何的user code之前执行。

 

 

下面的代码是在学习过程中随便写的,错误和不严谨之处很多;甚至有一些地方只是做了一些记录和随笔。

 

原创粉丝点击