C++虛函數與純虛函數的區別

什麼是虛函數?

那些被virtual關鍵字修飾的成員函數,就是虛函數。虛函數的作用,用專業術語來解釋就是實現多態性(Polymorphism),多態性是將接口與實現進行分離;用形象的語言來解釋就是實現以共同的方法,但因個體差異而採用不同的策略。

虛函數聲明如下:virtual ReturnType FunctionName(Parameter);

虛函數必須實現,如果不實現,編譯器將報錯,錯誤提示爲:

error LNK****: unresolved external symbol "public: virtual void __thiscall

ClassName::virtualFunctionName(void)"

 

爲什麼要用純虛函數?

在很多情況下,基類本身生成對象是不合情理的。例如,動物作爲一個基類可以派生出老虎、孔雀等子類,但動物本身生成對象明顯不合常理。爲了解決這個問題,方便使用類的多態性,引入了純虛函數的概念,將函數定義爲純虛函數(方法:virtual ReturnType Function()= 0;),則編譯器要求在派生類中必須予以重寫以實現多態性。同時含有純虛擬函數的類稱爲抽象類,它不能生成對象。

 

在什麼情況下使用純虛函數(pure vitrual function)?

 

1,當想在基類中抽象出一個方法,且該基類只做能被繼承,而不能被實例化;

 

2,這個方法必須在派生類(derived class)中被實現;

 

   如果滿足以上兩點,可以考慮將該方法申明爲pure virtual function.

 

我們來舉個例子,我們先定義一個形狀的類(Cshape),但凡是形狀我們都要求其能顯示自己。所以我們定義了一個類如下:

 

class CShape

 

{

 

    virtual void Show(){};

 

};

 

但沒有CShape這種形狀,因此我們不想讓CShape這個類被實例化,我們首先想到的是將Show函數的定義(實現)部分刪除如下:

 

class CShape
{
    virtual void Show();
};
當我們使用下面的語句實例化一個CShape時:

 

CShape cs;  //這是我們不允許的,但僅用上面的代碼是可以通過編譯(但link時失敗)。

 

 

 

   怎麼樣避免一個CShape被實例化,且在編譯時就被發現?

 

答案是:使用pure virtual funcion.

 

我們再次修改CShape類如下:

 

class CShape
{
public:
    virtual void Show()=0;
};
這時在實例化CShape時就會有以下報錯信息:
error C2259: 'CShape' : cannot instantiate abstract class due to following members:
warning C4259: 'void __thiscall CShape::Show(void)' : pure virtual function was not defined
 
我們再來看看被繼承的情況,我們需要一個CPoint2D的類,它繼承自CShape.他必須實現基類(CShape)中的Show()方法。
   其實使用最初的本意是讓每一個派生自CShape的類,都要實現Show()方法,但時常我們可能在一個派生類中忘記了實現Show(),爲了避免這種情況,pure virtual funcion發揮作用了。
   我們看以下代碼:
class CPoint2D:public CShape
{
public:
 CPoint2D()
 {
  printf("CPoint2D ctor is invoked\n");
 };
 void Msg()
 {
  printf("CPoint2D.Msg() is invoked\n");
 };
 
};
 
當我們實例化CPoint2D時,在編譯時(at the compiling)也會出現如下的報錯:
error C2259: 'CShape' : cannot instantiate abstract class due to following members:
warning C4259: 'void __thiscall CShape::Show(void)' : pure virtual function was not defined
   如上,我們預防了在派生類中忘記實現基類方法。
發佈了152 篇原創文章 · 獲贊 133 · 訪問量 96萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章