构造函数的寓意:default constructor

本文详细解析了c++标准中默认构造函数的合成过程及其适用的四种情况,包括带有默认构造函数的成员类对象、基类、虚拟函数类和虚拟基类的情况,并解释了默认构造函数的非平凡性与初始化顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c++标准中 默认构造函数在没有任何user-declared constructor的下,编译器会隐式地声明出来,而合成出来的default constructor 是没啥子用。default constructor 只是满足编译器的需要,而不是程序员的需要,所以并满足程序员的要求。什么时候会合成一个nontrivial default constructor(指的是编译器需要的) 为以下四种情况;


一、带有default constructor 的member Class Object

如果一个class没有任何constructor,但是内含一个member object,且其有default constructor,则该class的default constructor 就是nontrivial.但是这个合成的操作在constructor真正的被调用的时候才会发生。对于多个源文件内的合成操作,编译器以inline的方式合成,因为inline函数有static linkage,不会被当前文件以外者所看到。

class Foo
{
  public:Foo();
    Foo(int)...
}

class Bar{
public:
   Foo foo;
    char *str;
}
</pre><pre name="code" class="cpp">void foo_bar()
{
   Bar bar;//这里将要合成
   if(str){...}
}
<span style="background-color: rgb(255, 255, 255); font-family: Arial, Helvetica, sans-serif;"></span><pre name="code" class="cpp">inline Bar::Bar()
{
   foo.Foo::Foo();
}
上述代码中,编译器合成的default constructor 只负责初始化bar中的foo部分,而str成员的初始化时程序员的责任。

定义defautlt constructor为:

Bar::Bar()
{
   str=0;
}
但是由于user-defined constructor存在,编译器不会合成操作。对于foo部分的初始化,编译器会在上面的constructor中安插一些代码,在user code 执行之前,调用需要的default constrcutor.

Bar::Bar()
{
   foo.Foo::Foo();
   str=0;
}
如果内含多个class member object 时,将按照在class的声明顺序,逐个调用每个member object的default constructor

class Dopey{
public:
  Dopey();
}

class Sneezy()
{
public:
  Sneezy(int);
  Sneezy();
}

class Bashful()
{
 public:
      Bashful(); 
}


class Snow_White{
public:
  Dopey dopey;
  Sneezy sneezy;
  Bashful bashful;
private:
<span style="white-space:pre">	</span>int mutable;
}
</pre><pre name="code" class="cpp">Snow_White::Snow_White():sneezy(1024)
{
<span style="white-space:pre">	</span>mutable=2048;
}
上面的代码,编译器安插代码之后,像这样:

Snow_White::Snow_White():sneezy(1024)
{
<span style="white-space:pre">	</span>dopey.Dopey::Dopey();
<span style="white-space:pre">	</span>sneezy.Sneezy::Sneezy();
<span style="white-space:pre">	</span>bashful.Bashful::Bashful();
<span style="white-space:pre">	</span>mutable=2048;
}
二、带有default constructor 的base class

派生类的default constructor 是nontrivial的。

三、带有 virtual function 的class

合成default constructor在编译期间执行两个步骤:

a、virtual function table 由编译器产生,内含每个class的virtual funciton 的地址;

b、每个class object 内,额外的vptr由编译器产生,内含virtual function table的地址。

四、带有virtual base class的class

小结:以上四种情况造成编译器必须为未声明的constructor的classes合成一个default constructor。在c++标准中成为implicit nontrivial default constructor。合成出来的函数只是满足编译器的需要。只有base class subobject 和member class objects 才被初始化,其他的nonstatic data member(如整数、整数数组,整数指针),由程序员负责其初始化。两个常见的误解:1)、任何class 如果没有定义default constructor ,编译器会为我们合成一个;

2)、编译器合成的default constructor会显示的设定class内的每个data members的默认值。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值