程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 《Effective C++》讀書筆記09:絕不在構造和析構過程中調用virtual函數

《Effective C++》讀書筆記09:絕不在構造和析構過程中調用virtual函數

編輯:關於C++

首先明確一下,對於一個繼承體系,構造函數是從基類開始調用了,而析構函數則正 好相反,從最外層的類開始。

對於在構造函數中調用virtual函數,先舉個例子:

1 class Transaction //所有交易的基類
2 {
3 public:
4    Transaction();
5   virtual void logTransaction() const = 0;//日志記 錄,因交易類型的不同而有不同的記錄
6 }
7
8 Transaction::Transaction()//構造函數實現
9 {
10
11   logTransaction();//調用了日志記錄
12 }
13
14 class Sell: public Transaction
15 {
16 public:
17   virtual void logTransaction() const;
18
19 }

Sell類從基類中繼承,這時候如果執行:

1 Sell a; //派生類

則首先會執行Transaction的構造函數,而Transaction構造函數會調用Transaction版 本的logTransaction函數(記住:基類構造函數中的virtual函數不會下降到派生類中) 。

而大家都知道,基類中的logTransaction還沒有實現代碼,這顯然會產生一個連接錯 誤。

有如下的解決方法:將logTransaction聲明為非virtual函數,然後通過派生類向基類 傳遞參數的方法來實現。

1 class Transaction
2 {
3 public:
4   Transaction (const std::string& logInfo);
5   void logTransaction(const std::string& logInfo) const;//改成非virtual實現
6
7 };
8
9 Transaction::Transaction(const std::string& logInfo)
10 {
11
12   logTransaction(logInfo);//同樣在構造函數中調用
13 }
14
15 class Sell: public Transaction
16 {
17 public:
18    Sell()
19     :Transaction(createLog())//將log信息傳給基類構造函 數
20   {
21
22   }
23 }

如此一來,就是派生類將構造信息向上傳給基類構造函數,解決了這個問題。

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