[C++]深度探索C++对象模型——关于默认构造函数

原书第二章第一节的内容

关于Default constructor的概念:没有任何形参的constructor(注意,不是说编译器自动为类添加的才叫Default constructor)。

这一节主要讲了编译器什么时候为类添加Default constructor?

先说结论:四种情况下,编译器会自动合成implicit nontrivial default constructor。

  1. 带有Default constructor的member class object
  2. 带有Default constructor的Base class
  3. 带有Virtual function
  4. 带有Virtual base class

情况一:带有Default constructor的member class object

比如类A的某个成员变量是类B的一个对象,而类B是有Default constructor的,比如:

class Foo{public: Foo(); Foo(int); ...};
class Bar{public: Foo foo; char *str; ...};

这种情况下,Bar没有(显式地)定义自己的Default constructor,编译器会自动合成一个。合成出来的Default constructor也许类似下面的形式:

Bar::Bar()
{
    foo.Foo::Foo();
}

说明:

  1. 编译器在这里完成了对类成员对象的默认构造(调用了foo的默认构造函数),这属于编译器的职责。但是没有对str变量进行初始化(比如也许程序要求str=0),因为这属于类Bar的设计者(程序员)的工作。
  2. 如果类已经显式声明了一个default constructor并在其中对str初始化了。这时编译器会扩张原有的default constructor(实际上,会扩张所有的显式定义的constructor),在constructor的user code之前调用类成员对象的constructor。
  3. 如果一个类有多个member class objects,按照声明的顺序,扩张constructor的时候依次调用这些类成员变量的constructor。

情况二:带有Default constructor的Base class

如下:

class Base{public: Base(); ...};
class A : public Base{...};

说明:

  1. 如果类A没有任何constructor。编译器会自动合成一个Default constructor,然后调用Base的Default constructor。
  2. 如果类A有多个已定义的constructor。即使已定义的constructor中没有Default constructor,编译器也不会合成一个Default constructor,只会扩张每个已有的constructor,调用Base的Default constructor。

情况三:带有Virtual function

带有虚函数(自己定义的,或者继承而来的)时,需要对vtbl(虚函数表)和vptr(指向虚函数表的指针)进行相应设置以支持多态。

  1. 如果类没有任何constructor,编译器会自动合成一个Default constructor,完成对vtbl和vptr的设置。
  2. 如果类定义了constructor,编译器会扩展这些constructor,完成对vtbl和vptr的设置。

情况四:带有Virtual base class

与情况三类似,为了支持虚基类,编译器需要做一些工作。

 

总结:

这个四种情况下被合成出来的constructor只能满足编译器的需要(而不是程序需要)。可以看出来这四种情况要么调用了类成员或者基类的Default constructor,要么是为了支持virtual机制。

不满足这四种情况时,实际上不会合成一个Default constructor。常见误解会认为如果类没有定义Default constructor,编译器就会自动合成一个,这是不对的

还有一点值得注意:合成的Default constructor只会初始化那些有构造函数的成员变量。对于整数、数组、指针等基本类型,编译器合成的Default constructor不会处理。所以,又有一个误解认为编译器合成的Default constructor会为我们自动初始化所有的类成员变量,这也是错的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值