1.構造函數不能為虛函數 當我們將構造函數定義為虛函數時,會直接報錯: 首先回憶下以前學的virtual虛函數概念: 如果類定義了虛函數,創建對象時,則會分配記憶體空間,並且為該父類以及其所有子類的記憶體空間上額外分配一個虛函數表. 虛函數表的作用在於,存儲每個類的相同的虛函數名,然後每一次虛函數調用, ...
1.構造函數不能為虛函數
當我們將構造函數定義為虛函數時,會直接報錯:
首先回憶下以前學的virtual虛函數概念:
- 如果類定義了虛函數,創建對象時,則會分配記憶體空間,並且為該父類以及其所有子類的記憶體空間上額外分配一個虛函數表.
- 虛函數表的作用在於,存儲每個類的相同的虛函數名,然後每一次虛函數調用,都會去虛函數表查找地址
分析:
假如構造函數是虛函數的話,由於對象開始還未分配記憶體空間,所以根本就無法找到虛函數表,從而構造函數也無法被調用.所以構造函數是不能成為虛函數.
2. 析構函數可以為虛函數
首先回憶下析構函數:
當某個內對象被註銷時,編譯器會自動順序調用該類以及其父類的析構函數,而不會調用派生類的析構函數.
虛析構函數的好處
假如我們通過派生類生成基類對象時,如果析構函數是虛函數,則我們釋放其基類對象時,能使整個類(包括派生類)對象完全釋放,如果析構函數只是普通函數,則不能析構完全.
分析:
所以當我們在用多態的時候(通過基類來調用派生類成員函數),析構函數最好為虛函數
示例如下:
#include <iostream> using namespace std; class ClassBase { public: ClassBase(){}; virtual ~ClassBase() { cout<<"~ClassBase()"<<endl; } virtual void func() //虛函數成員 { cout<<"ClassBase: func()"<<endl; } }; class ClassDerived : public ClassBase { public: ClassDerived(){}; ~ClassDerived() { cout<<"~ClassDerived()"<<endl; } void func() //虛函數成員 { cout<<"ClassDerived: func()"<<endl; } }; int main() { ClassBase *p = new ClassDerived; p->func(); //通過多態來調用派生類虛函數 delete p; return 0; }
列印如下: