Chap2-构造函数语意学

如果一个类没有任何constructor,那么会有一个default constructor被隐式的声明出来,一个implicit default constructor将是一个trivial(无用的)constructor。但是在某些情况下,implicit default constructor将是一个nontrivial constructor,下面一一讨论:

由编译器合成nontrivial default constructor的四种情况:

1)带有default constructor 的 member class object(ps:不包括基本数据类型对象):

  • case 1:如果一个类没有任何constructors,但它包含一个member class object,那么这个类的implicit default constructor 会去调用member class object的default constructor。

class A
{
public:
	A(){cout<<"Class A Constructor!"<<endl;}
};

class B
{
public:
	A a;   // a is a member class object and class A has a default constructor.
};
void main()
{
	B b;   
}


  • case 2:如果一个类包含constructors(ps:不限定是default constructor),也包含带default constructor的member class object,但是没有在constructors中显示调用,那么编译器会扩张已存在的constructors,使其每个member class object得到初始化。
class A
{
public:
	A(){cout<<"Class A Constructor!"<<endl;}
};
class B
{
public:
	B(int){}  // Non-default constructor
	A a;   // a is a member class object and class A has a default constructor.
};
void main()
{
	B b(5);   
}


  • case 3:C++中以member class object 在类中的声明顺序来调用各个constructors。
class A
{
public:
	A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
};
class B
{
public:
	B(){cout<<"Class B Constructor!"<<endl;}  // Default constructor
};
class C
{
public:
	A a;  // Member class object
	B b;  // Member class object
};
void main()
{
	C c;   
}


2)带有default constructor 的 base class:
  • case 1:如果一个类没有任何constructors,但它派生自一个或多个带有default constructor 的 base class,那么这个类的implicit default constructor 会去调用base class 的 default constructor(按声明顺序调用)。
class A
{
public:
	A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
};
class B : public A{};
void main()
{   
	B b;
}


  • case 2:如果一个类包含constructors(ps:不限定是default constructor),且派生自一个或多个带有default constructor 的 base class,但是没有在constructors中显示调用,那么编译器会扩张已存在的constructors,使其每个上层base class 的 default constructor 得到调用(按声明顺序调用)。
class A
{
public:
	A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
};
class B : public A
{
public:
	B(){}
};
void main()
{  
	B b;
}


3)带有一个或多个virtual functions 的 class:
  • class声明(或继承)一个或多个virtual functions,那么编译器会在constructors(如果没有,则隐式创建一个default constructor)中隐式的进行一些扩张行动:创建一个virtual function table,内放class 的 virtual functions的地址(所以一个类中如果声明了virtual function(纯虚函数除外),就必须实现它,实现了才会有函数地址);在每一个class object中,创建一个额外的vft_ptr,内含virtual function table的地址。
// sizeof(A)=1
class A
{
public:
	A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
};

// sizeof(A)=4
class A
{
public:
	A(){cout<<"Class A Constructor!"<<endl;} // Default constructor
	virtual void foo(){}
};

4)带有一个或多个virtual base class 的 class:
  • class或继承一个或多个virtual base class,那么编译器会在constructors(如果没有,则隐式创建一个default constructor)中隐式的进行一些扩张行动:创建一个virtual base class table,内放virtual base class subobjects 的地址(所以要virtual派生自一个base class,那么这个base class必须提供default constructor,使得编译器能创建virtual base class 的 subobject);在每一个class object中,创建一个额外的vbt_ptr,内含virtual base class table的地址。
// sizeof(B)=1
class A{};
class B : public A{};
// sizeof(B)=4
class A{};
class B : public virtual A{};

总结:以上四种情况,会造成编译器为未声明constructor的类隐式生成一个default constructor,或者扩张已有的constructors使其满足编译器的需要。
posted @ 2012-05-26 11:17  刘军newhand_liu  阅读(177)  评论(0编辑  收藏  举报