1. 虛函數和純虛函數可以定義在同一個類(class)中,含有純虛函數的類被稱為抽象類(abstract class),而只含有虛函數的類(class)不能被稱為抽象類(abstract class)。
2. 虛函數可以被直接使用,也可以被子類(sub class)重載以後以多態的形式調用,而純虛函數必須在子類(sub class)中實現該函數才可以使用,因為純虛函數在基類(base class)
只有聲明而沒有定義。
3. 虛函數和純虛函數都可以在子類(sub class)中被重載,以多態的形式被調用。
4. 虛函數和純虛函數通常存在於抽象基類(abstract base class -ABC)之中,被繼承的子類重載,目的是提供一個統一的接口。
5. 虛函數的定義形式:virtual {method body}
純虛函數的定義形式:virtual { } = 0;
在虛函數和純虛函數的定義中不能有static標識符,原因很簡單,被static修飾的函數在編譯時候要求前期bind,然而虛函數卻是動態綁定(run-time bind),而且被兩者修飾的函數生命周期(life recycle)也不一樣。
6.如果一個類中含有純虛函數,那麼任何試圖對該類進行實例化的語句都將導致錯誤的產生,因為抽象基類(ABC)是不能被直接調用的。必須被子類繼承重載以後,根據要求調用其子類的方法。
以下為一個簡單的虛函數和純虛寒數的使用演示,目的是拋磚引玉!
#include <>
//father class
class Virtualbase
{
public:
virtual void Demon()= 0; //prue virtual function
virtual void Base() {cout<<"this is farther class"<<endl};
}
//sub class
class SubVirtual :public Virtualbase
{
public:
void Demon() { cout<<" this is SubVirtual!"<<endl};
void Base() { cout<<"this is subclass Base"<};
}
/* instance class and sample */
int main()
{
Virtualbase* inst = new SubVirtual(); //multstate pointer
inst->Demon();
inst->Base();
}
虛函數和純虛函數區別
觀點一:
類裡聲明為虛函數的話,這個函數是實現的,哪怕是空實現,它的作用就是為了能讓這個函數在它的子類裡面可以被重載,這樣的話,這樣編譯器就可以使用後期綁定來達到多態了
純虛函數只是一個接口,是個函數的聲明而已,它要留到子類裡去實現。
class A{
protected:
void foo();//普通類函數
virtual void foo1();//虛函數
virtual void foo2() = 0;//純虛函數
}
觀點二:
虛函數在子類裡面也可以不重載的;但純虛必須在子類去實現,這就像Java的接口一樣。通常我們把很多函數加上virtual,是一個好的習慣,雖然犧牲了一些性能,但是增加了面向對象的多態性,因為你很難預料到父類裡面的這個函數不在子類裡面不去修改它的實現
觀點三:
虛函數的類用於“實作繼承”,繼承接口的同時也繼承了父類的實現。當然我們也可以完成自己的實現。純虛函數的類用於“介面繼承”,主要用於通信協議方面。關注的是接口的統一性,實現由子類完成。一般來說,介面類中只有純虛函數的。
觀點四:
帶純虛函數的類叫虛基類,這種基類不能直接生成對象,(否則會出現錯誤!)而只有被繼承,並重寫其虛函數後,才能使用。這樣的類也叫抽象類。虛函數是為了繼承接口和默認行為
純虛函數只是繼承接口,行為必須重新定義。