1.虛函數
類Base中加了Virtual關鍵字的函數就是虛擬函數(例如函數print),於是在Base的派生類Derived中就可以通過重寫虛擬函數來實現對基類虛擬函數的覆蓋。當基類Base的指針point指向派生類Derived的對象時,對point的print函數的調用實際上是調用了Derived的print函數而不是Base的print函數。這是面向對象中的多態性的體現
基類的函數調用如果有virtual則根據多態性調用派生類的,如果沒有virtual則是正常的靜態函數調用,還是調用基類的。
class Base { public:Base(){} public: virtual void print(){cout<<"Base";} }; class Derived:public Base { public:Derived(){} public: void print(){cout<<"Derived";} }; int main() { Base *point=new Derived(); point->print(); }
Output:Derived
2.純虛函數:
C++語言為我們提供了一種語法結構,通過它可以指明,一個虛擬函數只是提供了一個可被子類型改寫的接口。但是,它本身並不能通過虛擬機制被調用。這就是純虛擬函數(purevirtual function)。 純虛擬函數的聲明如下所示:
class Query {
public:
// 聲明純虛擬函數
virtual ostream& print( ostream&=cout ) const = 0;
// ...
};
這里函數聲明后面緊跟賦值0。
包含一個或多個純虛擬函數的類被編譯器識別為抽象基類。抽象基類不能被實例化,一般用於繼承。
3.虛擬繼承(virtual public)
在多繼承下,虛繼承就是為了解決菱形繼承中,B,C都繼承了A,D繼承了B,C,那么D關於 A的引用只有一次,而不是 普通繼承的 對於A引用了兩次……
格式:可以采用public、protected、private三種不同的繼承關鍵字進行修飾,只要確保包含virtual就可以了。
class A { void f1(){}; }; class B : public virtual A{ void f2(){}; };
虛繼承:在繼承定義中包含了virtual關鍵字的繼承關系;
虛基類:在虛繼承體系中的通過virtual繼承而來的基類,
了解下概念,至於虛基類的初始化、以及虛繼承體系的進一步繼承問題暫不討論。
(C++標准中(也是很自然的)選擇在每一次繼承子類中都必須書寫初始化語句(因為每一次繼承子類可能都會用來定義對象),而在最下層繼承子類中實際執行初始化過程。所以上面在每一個繼承類中都要書寫初始化語句,但是在創建對象時,而僅 僅會在創建對象用的類構造函數中實際的執行初始化語句,其他的初始化語句都會被壓制不調用。)
詳見:http://www.cppblog.com/chemz/archive/2007/06/12/26135.html