1、構造函數不能是虛函數。因為構造函數不是一個普通的函數,要構造一個對象,構造函數必須掌握所創建的對象的確切類型,因此構造函數不能是虛的。
2、析構函數可以是虛函數。首先我們要搞清楚為什么要虛析構函數?這樣做是為了當用一個基類的指針刪除一個派生類的對象時,派生類的析構函數會被調用。也就是只有當靜態類型為基類,而動態類型為子類時,為了確保子類的析構函數能被調用,基類的析構函數必須被聲明為虛析構函數。
一般情況下類的析構函數里面都是釋放內存資源,而析構函數不被調用的話就會造成內存泄漏。當然,如果在析構函數中做了其他工作的話,那你的所有努力也都是白費力氣。
當然,并不是要把所有類的析構函數都寫成虛函數。因為當類里面有虛函數的時候,編譯器會給類添加一個虛函數表,里面來存放虛函數指針,這樣就會增加類的存儲空間。所以,只有當一個類被用來作為基類的時候,才把析構函數寫成虛函數。
3、純虛函數
聲明純虛函數的方法:
virtual void purefun()=0;
聲明一個純虛函數pure virtual 的目的就是讓Derived class只繼承函數接口,因為它沒有定義。但是實際上是可以有一份Defualt定義的,在使用時需要指出類名。如:
Derived->Base::Purefunction();
注意含有純虛函數的類是不能被實例化的。如果Base類中有一個純虛函數purefun(),Derived繼承了Base后必須對purefun()進行重寫,否則Derived也是一個函數純虛函數的類,同樣是不能被實例化的。
4、virtual函數的缺省參數值是靜態綁定的,所以記住決不要重新定義繼承而來的virtual 函數的缺省參數值。
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
class Base
{
public:
virtual void display(int i =1)
{
cout<<"Base Display"<<endl;
}
};
class Derived :public Base
{
public:
virtual void display(int i = 2)
{
if(i ==2)
cout<<"derived i==2"<<endl;
if(i == 1)
cout<<"derived i ==1"<<endl;
}
};
int main()
{
Base* p=new Derived();
p->display();
}
輸出是"derived i==1"