首页 > 代码库 > 深度探索C++对象模型-----编译器’何时‘自动合成nontrivial default constructor
深度探索C++对象模型-----编译器’何时‘自动合成nontrivial default constructor
有4种情况,会造成“编译器必须为 未申明constructor的classes合成default constructor。
1.带有default constructor的member class object
如果一个class没有任何constructor,但是内含一个member object ,而后者有default constructor,那么这个class的implicit default constructor就是 nontrivial,编译器需要为改class合成出一个default constructor。不过这个合成只有在constructor真正需要被调用时才发生。
程序片段:
class Foo{ public: Foo(); Foo(int); ......... }; class Bar{ public: Foo foo; char *str; ...... }; void foo_bar() { Bar bar;//Bar::foo必须在此处初始化 //Bar::foo是一个member object,而其class Foo拥有default constructor if(str) ..... }
被合成的Bar default constructor内含必要的代码,能够调用class Foo的default constructor来处理member object Bar::foo,但它并不产生任何代码来初始化Bar::str,将Bar::foo初始化是编译器的责任,将Bar::str初始化是程序员的责任。
如果程序员定义如下代码片段:
Bar::Bar(){str = 0;}
编译器的行动将会是:将class Bar中内含的Bar::foo调用foo的default constructor。编译器会将这些操作放在user code之前执行。扩张后的代码如下:
Bar::Bar(){ foo.Foo::Foo();//编译器安插代码,根据member object的申明顺序初始化 str = 0;//user code }2.带有default constructor的Base class
类似的道理,如果一个没有任何constructor的class 派生自一个带有default constructor的base class,那么这个derived class的default constructor会被视为nontrivial,并因此被合并出来。
如果设计者提供了多个constructors,但其中没有default constructor,编译器会扩张现存的每一个constructor,将用以调用所有必要之default constructor的程序代码加进去。它不会合成一个新的default constructor,因为其他由user所提供constructor存在的缘故。
如果存在default constructor的member class object,那么这些member的default也会被调用,在所有的base class constructor调用之后。
另外两种情况:
3.class 申明(继承)一个virtual function
4.class 派生自一个继承串链,其中有一个或更多的virtual base class。
总结:
以上四种情况,编译器必须为未申明constructor的class 合成一个default constructor。C++ Standard把这些合成物称为implicit nontrivial default constructor,被合成的constructor只能满足编译器的需要。
至于没有这四种情况而又没有申明任何constructor的class,我们说它们拥有的是implicit trivial default constructor,它们实际上并不会被合成出来。
在合成的default constructor中,只有base class subobject和member class object会被初始化,所有其他的nonstatic data member(如整数,整数指针,整数数组等)都不会被初始化。这些初始化都需要程序员操作。
C++新手一般有两个常见的误解:
1.任何class如果没有定义default constructor,就会被合成一个
2.编译器合成出来的default constructor会显式设定class 内每一个class member的默认值。
深度探索C++对象模型-----编译器’何时‘自动合成nontrivial default constructor