1. 虛函數和純虛函數能夠定義在同一個類(class)中,含有純虛函數的類被稱爲抽象類(abstract class),而只含有虛函數的類(class)不能被稱爲抽象類(abstract class)。html
2. 虛函數能夠被直接使用,也能夠被子類(sub class)重載之後以多態的形式調用,而純虛函數必須在子類(sub class)中實現該函數纔可使用,由於純虛函數在基類(base class)只有聲明而沒有定義。ios
3. 虛函數和純虛函數均可以在子類(sub class)中被重載,以多態的形式被調用。編程
4. 虛函數和純虛函數一般存在於抽象基類(abstract base class -ABC)之中,被繼承的子類重載,目的是提供一個統一的接口。函數
5. 虛函數的定義形式:virtual {method body}post
純虛函數的定義形式:virtual { } = 0;this
在虛函數和純虛函數的定義中不能有static標識符,緣由很簡單,被static修飾的函數在編譯時候要求前期bind,然而虛函數倒是動態綁定(run-time bind),並且被二者修飾的函數生命週期(life recycle)也不同。url
6. 虛函數必須實現,若是不實現,編譯器將報錯,錯誤提示爲:spa
error LNK****: unresolved external symbol "public: virtual void __thiscall
ClassName::virtualFunctionName(void)"指針
7. 對於虛函數來講,父類和子類都有各自的版本。由多態方式調用的時候動態綁定。code
8. 實現了純虛函數的子類,該純虛函數在子類中就編程了虛函數,子類的子類即孫子類能夠覆蓋
該虛函數,由多態方式調用的時候動態綁定。
9. 虛函數是C++中用於實現多態(polymorphism)的機制。核心理念就是經過基類訪問派生類定義的
函數
10. 多態性指相同對象收到不一樣消息或不一樣對象收到相同消息時產生不一樣的實現動做。C++支持兩種多態性:編譯時多態性,運行時多態性。
a.編譯時多態性:經過重載函數實現
b 運行時多態性:經過虛函數實現。
11. 若是一個類中含有純虛函數,那麼任何試圖對該類進行實例化的語句都將致使錯誤的產生,由於抽象基類(ABC)是不能被直接調用的。必須被子類繼承重載之後,根據要求調用其子類的方法。
#include<iostream> using namespace std; 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" << endl; } }; void main() { Virtualbase* inst = new SubVirtual(); //multstate pointer inst->Demon(); inst->Base(); // inst = new Virtualbase(); // inst->Base() system("pause"); return; }
1.虛函數(impure virtual)
C++的虛函數主要做用是「運行時多態」,父類中提供虛函數的實現,爲子類提供默認的函數實現。
子類能夠重寫父類的虛函數實現子類的特殊化。
以下就是一個父類中的虛函數:
class A { public: virtual void out2(string s) { cout<<"A(out2):"<<s<<endl; } };
2.純虛函數(pure virtual)
C++中包含純虛函數的類,被稱爲是「抽象類」。抽象類不能使用new出對象,只有實現了這個純虛函數的子類才能new出對象。
C++中的純虛函數更像是「只提供申明,沒有實現」,是對子類的約束,是「接口繼承」。
C++中的純虛函數也是一種「運行時多態」。
以下面的類包含純虛函數,就是「抽象類」:
class A { public: virtual void out1(string s)=0; virtual void out2(string s) { cout<<"A(out2):"<<s<<endl; } };
3.普通函數(no-virtual)
普通函數是靜態編譯的,沒有運行時多態,只會根據指針或引用的「字面值」類對象,調用本身的普通函數。
普通函數是父類爲子類提供的「強制實現」。
所以,在繼承關係中,子類不該該重寫父類的普通函數,由於函數的調用至於類對象的字面值有關。
程序綜合實例 --代碼實現
class A
{
public:
virtual void out1() = 0; ///由子類實現
virtual ~A() {};
virtual void out2() ///默認實現
{
cout << "A(out2)" << endl;
}
void out3() ///強制實現
{
cout << "A(out3)" << endl;
}
};
class B :public A
{
public:
virtual ~B() {};
void out1()
{
cout << "B(out1)" << endl;
}
void out2()
{
cout << "B(out2)" << endl;
}
void out3()
{
cout << "B(out3)" << endl;
}
};
int main()
{
A *ab = new B();
ab->out1();
ab->out2();
ab->out3();
cout << "************************" << endl;
B *bb = new B;
bb->out1();
bb->out2();
bb->out3();
delete ab; delete bb; return 0;}