程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++構造函數詳解

c++構造函數詳解

編輯:C++入門知識

c++構造函數詳解


一、Default constructor

1. 對於class X ,如果沒有任何user-declared constructor,那麼編譯器生成的default constructor是無用的

2. 編譯器合成(擴張)的default constructor 是有用的4中情況

①.帶有default constructor的member class object

Member class object 的Default constructor會在合成(擴張)的default constructor調用。

②.帶有default constructor的base class

合成(擴張)的default constructor會調用base class的default constructor

③.帶有一個virtual funtion的class

合成(擴張)的default constructor會初始化類的vptr

④.帶有一個virtual base class的class

3. 誤區

①.任何class如果沒有定義default constructor,就會被合成出來。

②.編譯器合成出來的default constructor 會被明確設定class內的每一個data member的默認值。

二、Copy constructor

1. 有三種情況,會以一個object的內容作為另一個class的初值。

①.明確的以一個object的內容作為另一個class object的初值 X xx = x;

②.當object被當作參數交給某個函數時 void foo(X x)

③.當函數傳回一個class object x = foo() { return xx;}

如果定義了copy constructor則大多數情況下會被調用,否則其內部是以所謂的default memberwise initialization 手法完成,對於其中member class object是以遞歸方式施行memberwise initialization。

 

2. 編譯器會合成copy constructor的情況即class不表現出bitwise copy semantics

①.當class內含一個member object而後者的class聲明有一個copy constructor時(具備條件合成的)

②.當class繼承自一個base class而後者存在有一個copy constructor(被明確聲明或被合成)

③.當class聲明了一個或多個virtual funtions時

④.當class派生自一個繼承串鏈,其中有一個或多個virtual base classes時

下面對第三點做簡要說明:

我們知道編譯期間的兩個程序擴張操作(有virtual funtion存在的前提下)

I.增加一個virtual function table(vtbl),內含每一個有作用的virtual function的地址

II.將一個指向virtual function table的指針(vptr),安插在每一個class object內

從這兩點我們可以看出編譯器需要合成出一個copy constructor以求將vptr適當的初始化。

class ZooAnimal

{

public:

ZooAnimal(){}

virtual ~ZooAnimal(){}

virtual void animate(){}

virtual void draw() {}

};

 

class Bear : public ZooAnimal

{

public:

Bear(): b(5){memset(this, 0, sizeof(Bear));}

virtual void animate(){}

virtual void draw() {}

virtual void dance(){}//父類沒有的虛函數

};

Bear yogi;

Bear winnine = yogi;

這種情況下yogi的vptr值拷貝給winner的vptr是安全的,也就說此時兩個對象的vptr完全一樣。

但是下面這種情況

ZoonAnimal franny = yogi;

此時franny的vptr不可以被設定指向Bear class的virtual table。也就說合成出來的ZoonAnimal copy constructor會明確設定object的vptr指向ZoonAnimal class的virtual table,而不是直接從右手邊的class object將其vptr現值拷貝過來

 

三、成員初值列(member initialization list)

1. 為了通過編譯必須使用member initialization list的情況

① 當初始化一個reference member

② 當初始化一個const member

③ 當調用一個base class的constructor,而它擁有一組參數時

④ 當調用member class的constructor,而它擁有一組參數時

初始化順序不是有list中的項目順序而是有member聲明次序決定;編譯器會一一操作initialization list根據聲明次序在constructor內安插初始化操作,並且在任何explicit user code之前。

 

 

版權聲明:本文為博主原創文章,未經博主允許不得轉載。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved