天天看點

深度探索C++ 對象模型(3)-預設構造函數Default Constructor

1. Default Constructor隻對base class subobjects和member class objects初始化,對data member不做操作

2. 編譯器構造Default Constructor 隻在下面4種case:

  • 1.包含有帶預設構造函數的對象成員的類 .
  • 2.繼承自帶有預設構造函數的基類的類 .
  • 3.有虛函數的類(需要初始化每一個class object的vptr) .
  • 4.有一個虛基類的類

本文主要針對"包含有帶預設構造函數的對象成員的類"

class Foo {
		public:
			Foo() { 
				cout << "Foo Constructor" << endl; 
			} 
			Foo(int) { 
			}
	};
  
	void test_defaultConstructor()
	{
		cout << "begin" << endl;
		Bar bar;
		cout << "end" << endl;
	}
           

(1). 若無定義構造函數

class Bar {  
		private: Foo foo; 
}; 
           

編譯器的對類Bar的Default Constructor為

Bar::Bar(){
     foo.Foo::Foo();//調用Foo的構造函數來初始化foo對象
}
           

運作測試代碼,輸出結果為:

begin

Foo Constructor

end

(2). 若有構造函數

Bar::Bar()
{
    cout << "Bar default code" << endl; 
}
           

此時編譯器擴充已知構造函數:

Bar::Bar(){
     foo.Foo::Foo();//調用Foo的構造函數來初始化foo對象
     cout << "Bar default code" << endl; 
}
           

運作測試代碼,輸出結果為:

begin

Foo Constructor

Bar default code

end

(3). 若有多個class member objects都要求constructor初始化,将按照在classs中的聲明次序調用

class Dopey {
		public:Dopey() {
			cout << "Dopey Constructor" << endl;
		}
	};

	class Sneezy {
		public:Sneezy() {
			cout << "Sneezy Constructor" << endl;
		}
	};

	class Bashful {
		public:Bashful() {
			cout << "Bashful Constructor" << endl;
		}
	};
	 

	class Snow_White { 
		private:
			Dopey dopey;
			Sneezy sneezy;
			Bashful bashful;
			int mumble; 
	};

	void test_defaultConstructor()
	{
		cout << "begin" << endl;
		Snow_White obj;
		cout << "end" << endl;
	}
           

運作測試代碼,輸出結果為:

begin

Dopey Constructor

Sneezy Constructor

Bashful Constructor

end

(4). 如果基類有預設構造函數,又有一個成員有預設構造函數,那麼順序是誰先呢?

class SnowWhite : public Dopey{ 
	private: 
		Sneezy sneezy; 
	};

	void test_defaultConstructor_ObjectOrder()
	{
		cout << "begin" << endl;
		SnowWhite obj;
		cout << "end" << endl;
	}
           

運作測試代碼,輸出結果為:

begin

Dopey Constructor

Sneezy Constructor

end

【引用】

[1]<<深度探索C++ 對象模型 Inside The C++ Object Model >> Stanley B.Lippman 候捷 譯

[2] 代碼位址 https://github.com/thefistlei/cplusStudy.git