构造函数与拷贝构造函数

来源:互联网 发布:王虎应六爻软件 编辑:程序博客网 时间:2024/05/16 10:42

       关于构造函数和拷贝构造函数,一直以来的印象是,只要我没有人工实现,系统就会为我们指定一个默认的函数,也就是我们一般所说的默认构造函数和默认拷贝构造函数,最近在看《深度探索c++对象模型》的时候,发现并不是这样的,程序或者说编译器,只在编译器需要的时候指定默认的构造函数。书中用了trivial这个词,只有在nontrivial的时候,才会生成默认构造函数。

首先说下什么时候会生成default constructor,有以下三种情况:

    (1)带有default constructor的member class object

    (2)带有default constructor的Base class

    (3)带有一个Virtual Function的class

    (4)class继承自一个或多个虚基类

对于第一种情况,考虑如下的class

class A{

public:

     B b;

}

如果B这个类有默认构造函数的话,则A也有默认构造函数

第二种情况很好理解,如果基类有默认构造函数,则派生类也有默认构造函数

第三种情况是,如果这个类中有虚函数,则也要有默认构造函数,有的文章强调是继承串链中有虚函数,其实不必强调,因为若某个函数在基类中有虚函数的话,则派生类中一定也是虚函数,一样的道理。

第四种情况和第三种情况类似,本质上也是由于虚表的存在,需要在构造的过程中判断。

       其实死记硬背这些情况意义不大,只要真正理解为什么是这样就是了,书中有一句话:“默认的构造函数并不是为了满足程序的需要而产生的,而是为了满足编译器的需要”,那么假设我实例化一个对象,没有什么赋值的、初始化之类的,只是划分块空间就可以了,那还构造什么函数,反观这几种情况,要么是有虚表指针需要构建,要么是有其他的构造函数(不管是成员变量中的对象还是父类对象)或者是需要动态判断成员函数的所属,也就是类除了划分一块内存以外,还有些别的操作需要进行,这种情况下才会需要一个构造函数来实现这些额外的操作,这种情况就被称作nontrivial。

       现在再来看看默认的拷贝构造函数,有了默认构造函数的底子,拷贝构造函数就好理解多了,在拷贝构造函数中也有一个衡量是否是trivial的词——Bitwise Copy Semantics(位逐次拷贝),先别管这个词是啥意思,先来看看生成默认拷贝构造函数的情况:

    (1)class内含一个member object,且该class声明有一个copy constructor

    (2)class继承自一个base class,该class存在一个copy constructor

    (3)class声明了virtual functions

    (4)class继承的串链中包含一个或多个vitual base classes

        很明显,拷贝构造函数的情况和默认构造函数如出一辙,其思想也是基本一致,当一个对象在拷贝的时候,除了Bitwise Copy Semantics以外,没有额外的操作,则无需拷贝构造函数,若有虚表指针的显式转换、其他的拷贝构造函数等需要调用,这个时候就需要构建一个默认的拷贝构造函数来实现对应的功能。

        那么Bitwise Copy Semantics是什么意思呢,实际上,就是每个指针、每个对象、每个成员变量挨个赋值的意思,例如下面的class:

class A{

public:

    int a;

    char b;

    ...

}

实例一个A对象,A a1

再令A  a2 = a1

此时的操作就是a2.a = a1.a; a2.b = a1.b

这就是位逐次拷贝,这种情况下是不需要拷贝构造函数的

个人理解,不一定对,c++这些底层的部分太难理解

原创粉丝点击