建構函式和複製控制成員

2021-07-04 09:02:07 字數 2457 閱讀 8995

建構函式和複製控制成員不能繼承(即建構函式,析構函式,複製建構函式,賦值操作符),每個類定義自己的建構函式和複製控制成員。像任何類一樣,如果類不定義自己的預設建構函式和複製控制成員,就將使用合成版本。

²  派生類建構函式

派生類的建構函式受繼承關係的影響,每個派生類建構函式除了初始化自己的資料成員之外,還要初始化基類。派生類的合成預設建構函式與非派生的建構函式只有一點不同:除了初始化派生類的資料成員之外,它還初始化派生類物件的基類部分。基類部分由基類的預設建構函式初始化。

向基類建構函式傳遞實參,派生類建構函式的初始化列表只能初始化派生類的成員,不能直接初始化繼承成員。派生類建構函式通過將基類包含在建構函式初始化列表中來間接初始化繼承成員。如:

bulk_item(const std::string&book, double sales_price,std::size_t qty = 0, double disc_rate = 0.0):item_base(book, sales_price),min_qty(qty),discount(disc_rate)

ps:建構函式初始化列表為類的基類和成員提供初始值,它並不指定初始化的執行次序。首先初始化基類,然後根據變數宣告次序初始化派生類的成員。

pps:派生類建構函式只能初始化自己的直接基類,在 派生類的建構函式初始化列表中指定間接基類是乙個錯誤。

²  複製控制

類是否需要定義複製控制成員完全取決於類自身的直接成員。基類可以定義自己的複製控制而派生類使用合成版本,反之亦然。item_base類及其派生類可以使用複製控制操作的合成版本。複製bulk_item 物件時, 呼叫 (合成的) item_base 複製建構函式複製 isbn 和 price

成員。使用 string 複製建構函式複製 isbn,直接複製 price 成員。一旦複製了基類部分,再複製派生部分。bulk_item 的兩個成員都是 double 型,直接複製這些成員。賦值操作符和析構函式類似處理。

²  定義派生類的複製建構函式

如果派生類定義了自己的複製建構函式,該複製建構函式一般應顯式使用基類複製建構函式初始化物件的基類部分:

class base;

classderived: public base };

初始化函式 base(d) 將派生類物件 d 轉換為它的基類部分的引用,並呼叫基類複製建構函式。

²  派生類賦值操作符

賦值操作符通常與複製建構函式類似:如果派生類定義了自己的賦值操作符,則該操作符必須對基類部分進行顯式賦值。

// base::operator=(const base&) not invoked automatically

derived& derived::operator=(const derived &rhs)

return *this; }

²  派生類析構函式

析構函式的工作與複製建構函式和賦值操作符不同:派生類析構函式不負責撤銷基類物件的成員。編譯器總是顯式呼叫派生類物件基類部分的析構函式。每個析構函式只負責清除自己的成員:

classderived: public base };

物件的撤銷順序與構造順序相反:首先執行派生析構函式,然後按繼承層次依次向上呼叫各基類析構函式。

²  虛析構函式

刪除指向動態分配物件的指標時,需要執行析構函式在釋放物件的記憶體之前清除物件。處理繼承層次中的物件時,指標的靜態型別可能與被刪除物件的動態型別不同,可能會刪除實際指向派生類物件的基類型別指標。如果刪除基類指標,則需要執行基類析構函式並清除基類的成員,如果物件實際是派生型別的,則沒有定義該行為。要保證執行適當的析構函式,基類中的析構函式必須為虛函式:

classitem_base };

item_base*itemp = new item_base;

deleteitemp;              // ok: destructor foritem_base called

itemp =new bulk_item;

deleteitemp;               // ok: destructor forbulk_item called

像其他虛函式一樣,析構函式的虛函式性質都將繼承。因此,如果層次中根類的析構函式為虛函式,則派生類析構函式也將是虛函式,無論派生類顯式定義析構函式還是使用合成析構函式,派生類析構函式都是虛函式。即使析構函式沒有工作要做,

繼承層次的根類

也應該定義乙個空的虛析構函式。

*****建構函式和賦值操作符不是虛函式*******

在複製控制成員中,只有析構函式應定義為虛函式,建構函式不能定義為虛函式。建構函式是在物件完全構造之前執行的,在建構函式執行的時候,物件的動態型別還不完整。

將賦值操作符設為虛函式可能會令人混淆,因為虛函式必須在基類和派生類中具有同樣的形參(即基類物件的引用)。但是,

對派生類而言,

這個操作符與賦值操作符是不同的。

複製控制成員總結

1.複製控制成員是指 複製建構函式 賦值操作符函式 析構函式 2.關於複製建構函式,見 複製建構函式總結 3.如果沒有自己的賦值操作符函式,編譯器會提供乙個。賦值操作符也是依次複製每個非static成員,也是淺層複製。賦值操作符與複製構造的區別,只是不用為物件開闢新空間。4.析構物件的順序,是建立物...

C 理解拷貝控制成員和建構函式

首先通過例子分析 建構函式,拷貝建構函式,拷貝賦值運算子,析構函式 何時呼叫?定義類test class test 拷貝建構函式 test operator const test 拷貝賦值運算子 test private inline test test inline test test 測試函式f...

C 編譯器合成預設建構函式和複製控制成員的條件

參考自 深入理解c 物件模型 c 新手一般有兩個常見的誤解 任何class如果沒有定義default constructor,就會被合成乙個出來.編譯器合成出來的default constructor會明確設定class 內每乙個data member的預設值.現在主要解釋第一條為什麼是錯誤的,根據...