构造函数不可以声明为虚函数,析构函数可以声明为虚函数
構造函數不能聲明為虛函數,而析構函數可以聲明為虛函數,在有的情景下析構函數必須聲明為虛函數。?
不建議在構造函數和析構函數里調用虛函數。
構造函數不能聲明為虛函數的原因?
構造一個對象時,必須知道對象實際類型,而虛函數是在運行期間確定實際類型的。而在構造一個對象時,由于對象還未構造成功,編譯器就無法知道對象的實際類型,是該類本身,還是派生類,還是其他。
虛函數的執行依賴于虛函數表,而虛函數表是在構造函數中進行初始化的,即初始化虛表指針(vptr),使得正確指向虛函數表。而在構造對象期間,虛函數表(vtable)還沒有被初始化,將無法進行。
析構函數設為虛函數的原因?
當基類指針指向子類對象的時候,當調用基類的析構函數釋放內存時,由于析構函數不具有多態性,因此只會執行基類的析構函數,子類內存無法釋放,因此造成內存泄漏。
當將基類的析構函數設定為虛函數的話,當調用基類的析構函數釋放內存時,會先去執行子類的析構函數釋放子類的內存,之后再調用基類的析構函數,釋放基類的內存。
析構函數的作用在對象撤銷前把類的對象從內存中撤掉,通常系統只會執行基類的析構函數,不執行派生類的析構函數。
將基類的析構函數聲明為虛函數,當撤銷基類對象的同時也撤銷派生類的對象,這個過程是動態關聯完成的。
析構函數設為虛函數的原因是為了防止內存泄露。在繼承體系中,當基類的指針或引用指向派生類,用基類delete時,如果析構函數沒有聲明為虛函數,只能析構基類對象,派生類對象將無法析構。
建議將析構函數設為虛函數。
?
當想使用子類的指針直接釋放子類的對象時,會先執行子類的析構函數,再執行基類的析構函數,再執行基類的基類的析構函數,以此類推!
說明:
使用虛函數,系統會有一定的空間開銷。當一個類帶有虛函數時,編譯系統會為該類構造一個虛函數表,是一個指針數組,存放每個虛函數的入口地址。系統在進行動態關聯的時間開銷很少,提高了多態性的效率。
編譯器生成的析構函數都是非虛的,除非是一個子類,其父類有個虛析構函數,此時的虛函數特性繼承自基類。
有虛函數的類,一般情況下要定義一個虛析構函數。
純虛函數
在有的情景下,基類的虛函數是為了派生類中的使用而聲明定義的,但在基類中沒有任何意義,此類函數稱為純虛函數,不需要寫成空函數的形式,只需要在聲明為以下格式:
virtual 函數類型 函數名(形參列表) = 0;
1
純虛函數是沒有函數體的,“=0”并不代表函數的名字不具備函數的功能,不能被調用,在派生類中對該函數定義后,才能具備函數的功能,可以被調用。
?
?
總結
以上是生活随笔為你收集整理的构造函数不可以声明为虚函数,析构函数可以声明为虚函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++面向对象基础(二)
- 下一篇: 关于STL几点