Effective C++ T09:絕不在構造和析構過程中調用virtual函數

Effective C++學習筆記總鏈接

改善程序與設計的55個具體做法學習筆記-每日1條


條款09:絕不在構造和析構過程中調用virtual函數

【技巧】

在構造和析構期間不要調用virtual函數,因爲這類調用從不下降至derived class(比起當前執行構造函數和析構函數的那層)


class Transaction // 所有交易的base class
{
   
     
public:
	Transaction();
	virtual void logTransaction() const = 0; // 做一份因類型不同而不同的日誌記錄(log entry)
};
Transaction::Transaction()
{
   
     
	logTransaction();
}
class BuylogTransaction: public logTransaction // derived class
{
   
     
	virtual void logTransaction() const;
};

...
BuylogTransaction b; // 執行會發生什麼事?

無疑會有個BuylogTransaction 構造函數被調用,但首先Transaction構造函數一定會被調用。
Transaction構造函數會執行virtual函數 logTransaction,但調用的是Transaction::logTransaction(),而不是BuylogTransaction ::logTransaction()。

base class構造期間virtual函數絕不會下降到derived class階層

或者說是,在base class 構造期間,virtual函數不是virtual 函數。

原因】:由於base class構造函數執行更早於derived class構造函數,當base class構造函數執行時derived class的成員變量尚未初始化。

根本原因】:在derived class對象的base class 構造期間,對象的類型是base class 而不是derived class。virtual虛函數(或者運行期類型信息(dynamic_cast 條款27和typeid))會被編譯器解析至base class類型

對象在derived class構造函數開始執行前不會成爲一個derived class對象。

相同的道理也適用於析構函數。

換句話說,由於你無法使用virtual函數從base class 向下調用, 在構造期間,你可以藉由“令derived class 將必要的構造信息向上傳遞至 base class 構造函數” 替換之二加以彌補。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章