C C 問答 3 關於構造和析構函式使用多型

2021-05-11 03:25:13 字數 1250 閱讀 6419

問:

在構造或析構期間能使用虛函式嗎?

答:

能,但最好不要這麼做。

前兩天在公司遊戲專案開發過程中,在析構函式中不小心呼叫了虛函式,而且還是個純虛函式。

因為一直是在rlease模式下工作的,導致系統直接終止客戶端,雖然控制台有列印這個錯誤,但終止太快,也沒看到。切換在debug下除錯,則會報r6025 -pure virtual function call 的執行時錯誤。

當然,如果在析構函式中直接呼叫純虛函式,編譯器也不傻(vs2008),它不會讓編譯通過的,因為純虛函式沒有實現體,所以會出現unresolved external symbol鏈結錯誤。但是通過其他函式間接呼叫,編譯器就不會發現,就會出錯。

直接看下面這個例子吧

class testeffect

~testeffect()

void release()

virtual void clear() = 0;

};class subtesteffect: public testeffect

~subtesteffect(){}

virtual void clear()

};這樣new出來乙個subtesteffect的例項,在delete時就會崩潰。

就這個例子,說一下關於構造和析造函式中使用多型

一、構造派生類物件時,首先呼叫基類建構函式,執行基類初始化。而物件的派生類部分是未初始化的。實際上此時物件還不是乙個派生類物件。

二、析構派生類物件時,首先析構它的派生類部分,然後按照與構造順序的逆序呼叫它的基類析構。

這兩種情況下,物件都不是完整的。為了適應這種不完整,編譯器將物件的型別視為在構造或析造期間發生了變化。在基類構造或析構函式中,將派生類物件當作基類型別物件來對待。

構造或析構期間的物件型別對虛函式的繫結有影響。

所以如果在構造或析構函式中使用多型,則執行的是為建構函式或析構函式自身型別定義的版本。無論是由建構函式(或析構函式)直接呼叫虛函式,或者從建構函式(或析構函式)所呼叫的函式間接呼叫虛函式,都應用這種繫結。

《effective c++》第三版中條款09,scott meyers就明確指出:決不在構造或析造過程中呼叫virtual函式,講的詳細且權威。有人說c++程式設計師分為兩類,讀過effective c++的和沒讀過的,很遺憾,我是後者。

告誡自己不要在構造或析構過程中呼叫虛函式。

注意:「不要」和「不能」,允許呼叫,但可能達不到你的預斯結果,甚至會導致崩潰。 

關於構造,析構,拷貝建構函式,

1.建構函式 2.析構函式 3.拷貝建構函式 4.賦值語句 5.位址過載運算子 取址符 6.對const取物件的位址符 一.建構函式 1.關鍵字explicit 在建構函式前加上explicit時建構函式必須顯示呼叫 例如test是類名,有乙個test的建構函式,有兩個引數。若果加上關鍵字expli...

C C 筆記 之建構函式,析構函式

構造方法用來初始化類的物件,與父類的其它成員不同,它不能被子類繼承 子類可以繼承父類所有的成員變數和成員方法,但不繼承父類的構造方法 因此,在建立子類物件時,為了初始化從父類繼承來的資料成員,系統需要呼叫其父類的構造方法。如果沒有顯式的建構函式,編譯器會給乙個預設的建構函式,並且該預設的建構函式僅僅...

建構函式和析構函式

建構函式沒有返回值,不能被顯示的呼叫。它是在定義物件時由系統自動執行的,而且只執行一次。如果沒有定義建構函式,系統會自動生成乙個建構函式,只是這個建構函式的函式體是空,沒有引數,也不執行任何初始化的操作。帶引數的建構函式 有一種簡練,方便的寫法 建構函式的引數初始化表 box int h,int w...