程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++基礎知識 >> C++虛函數詳解

C++虛函數詳解

編輯:C++基礎知識
虛函數對於多態具有決定性的作用,有虛函數才能構成多態,這節我們來重點說一下虛函數的注意事項。

1) 只需要在虛函數的聲明處加上 virtual 關鍵字,函數定義處可以加也可以不加。

2) 為了方便,你可以只將基類中的函數聲明為虛函數,這樣所有派生類中具有遮蔽(覆蓋)關系的同名函數都將自動成為虛函數。關於名字遮蔽已在《C++繼承時的名字遮蔽》一節中進行了講解。

3) 當在基類中定義了虛函數時,如果派生類沒有定義新的函數來遮蔽此函數,那麼將使用基類的虛函數。

4) 只有派生類的虛函數遮蔽基類的虛函數(函數原型相同)才能構成多態(通過基類指針訪問派生類函數)。例如基類虛函數的原型為virtual void func();,派生類虛函數的原型為virtual void func(int);,那麼當基類指針 p 指向派生類對象時,語句p -> func(100);將會出錯,而語句p -> func();將調用基類的函數。

5) 構造函數不能是虛函數。對於基類的構造函數,它僅僅是在派生類構造函數中被調用,這種機制不同於繼承。也就是說,派生類不繼承基類的構造函數,將構造函數聲明為虛函數沒有什麼意義。

6) 析構函數可以聲明為虛函數,而且有時候必須要聲明為虛函數,這點我們將在下節中講解。

構成多態的條件

站在“學院派”的角度講,封裝、繼承和多態是面向對象的三大特征,封裝、繼承分別在《C++類成員的訪問權限》《C++繼承與派生》中進行了講解,而多態是指通過基類的指針既可以訪問基類的成員,也可以訪問派生類的成員。

下面是構成多態的條件:
  • 必須存在繼承關系;
  • 繼承關系中必須有同名的虛函數,並且它們是遮蔽(覆蓋)關系。
  • 存在基類的指針,通過該指針調用虛函數。

下面的例子對各種混亂情形進行了演示:
#include <iostream>
using namespace std;

//基類Base
class Base{
public:
    virtual void func();
    virtual void func(int);
};
void Base::func(){
    cout<<"void Base::func()"<<endl;
}
void Base::func(int n){
    cout<<"void Base::func(int)"<<endl;
}

//派生類Derived
class Derived: public Base{
public:
    void func();
    void func(char *);
};
void Derived::func(){
    cout<<"void Derived::func()"<<endl;
}
void Derived::func(char *str){
    cout<<"void Derived::func(char *)"<<endl;
}

int main(){
    Base *p = new Derived();
    p -> func();  //輸出void Derived::func()
    p -> func(10);  //輸出void Base::func(int)
    p -> func("http://c.biancheng.net");  //compile error

    return 0;
}
在基類 Base 中我們將void func()聲明為虛函數,這樣派生類 Derived 中的void func()就會自動成為虛函數。p 是基類 Base 的指針,但是指向了派生類 Derived 的對象。

語句p -> func();調用的是派生類的虛函數,構成了多態。

語句p -> func(10);調用的是基類的虛函數,因為派生類中沒有函數遮蔽它。

語句p -> func("http://c.biancheng.net");出現編譯錯誤,因為通過基類的指針只能訪問從基類繼承過去的成員,不能訪問派生類新增的成員。

什麼時候聲明虛函數

首先看成員函數所在的類是否會作為基類。然後看成員函數在類的繼承後有無可能被更改功能,如果希望更改其功能的,一般應該將它聲明為虛函數。如果成員函數在類被繼承後功能不需修改,或派生類用不到該函數,則不要把它聲明為虛函數。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved