inside C++笔记之默认构造函数

来源:互联网 发布:莫言最好的作品 知乎 编辑:程序博客网 时间:2024/04/28 05:57

C++ Annotated Reference Manual告诉我们:“default constructors…在需要的时候别编译器产生出来”。这里的需要是编译器的需要,不是程序的需要,程序的需要是程序员的责任。

编译器合成出一个default constructor只执行编译器所需的行动。也就是说如果一个class没有任何构造函数,编译器不一定会为它合成一个defualt construtor。只有以下4中情况,编译器才会为class在需要的时候合成一个default constructor.

i.                    带有default constructorsmember class object.

例如:

class Foo { public: Foo(), Foo( int ) ... }; 
class Bar { public: Foo foo; char *str; }; 
void foo_bar() { 
   Bar bar; // Bar::foo must be initialized here 
   if ( str ) { } ... 
}
这里的Bar就被合成了一个default constructor。合成的目的就是调用Foodefault constructor。但它不对str做任何处理,这是程序员的责任。如果class中有多个member class objectdefautl constructor,则按照在class中声明次序依次调用它们的default constructor.
 
ii.                  带有default constructorbase class
例如:
Class Base { public: Base()……}
Class Dervce:public Base {…}
Void bd(){
    Dervce de;/Base /must be initialize here
}
这个Dervce在需要的时候编译器为其合成了一个default constructor。合成的目的就是调用基类的defualt constructor。如果有多个,按照声明的次序依次调用。
 
iii.                带有一个virtual functionclass

另外两种情况也需要合成defualt constructor.

1.       class 声明(或继承)一个virtual function.

2.       class 派生自一个继承串链,其中有一个或更多的virtual base classes.

例如:

class Widget {

public:

   virtual void flip() = 0;

};

void flip( const Widget& widget ) { widget.flip(); }

// presuming Bell and Whistle are derived from Widget

void foo() {

   Bell b;  Whistle w;

   flip( b );

   flip( w );

}

下面的两个扩展操作将会发生在编译期间发生:

1.       一个vtbl会被编译器产生出来,内放classvirtual地址。

2.       在每一个class object中,一个额外的vptr会编译器合成出来。

合成的目的就是为vptr设定处置。对于class的每一个construction,编译器都会插入相关代码,如果没有default constructor,编译器会合成一个。

 

 

iv.                 带有一个virtual base calssclass

Virtual base calss 的实现方法在不同的编译器之间有极大的差异,然而,每一种实现法的共通点在于必须使virtual base 在其每一个derived class object中的位置在执行期准备妥当。

原创粉丝点击