重載與覆蓋的區別3

 
7-1和例8-1很好理解,我把這兩個例子放在這裏,是讓大家作一個比較擺了,也是爲了幫助大家更好的理解:
        7-1中,派生類沒有覆蓋基類的虛函數,此時派生類的vtable中的函數指針指向的地址就是基類的虛函數地址。
        8-1中,派生類覆蓋了基類的虛函數,此時派生類的vtable中的函數指針指向的地址就是派生類自己的重寫的虛函數地址。
在例7-28-2看起來有點怪怪,其實,你按照上面的原則對比一下,答案也是明朗的:
        7-2中,我們爲派生類重載了一個函數版本:void fun(double d) 其實,這只是一個障眼法。我們具體來分析一下,基類共有幾個函數,派生類共有幾個函數:
類型
基類
派生類
Vtable部分
void fun(int i)
指向基類版的虛函數void fun(int i)
靜態部分
 
void fun(double d)
 
我們再來分析一下以下三句代碼
Base *pb = new Derive();
pb->fun(1);//Base::fun(int i)
pb->fun((double)0.01);//Base::fun(int i)
 
這第一句是關鍵,基類指針指向派生類的對象,我們知道這是多態調用;接下來第二句,運行時基類指針根據運行時對象的類型,發現是派生類對象,所以首先到派生類的vtable中去查找派生類的虛函數版本,發現派生類沒有覆蓋基類的虛函數,派生類的vtable只是作了一個指向基類虛函數地址的一個指向,所以理所當然地去調用基類版本的虛函數。最後一句,程序運行仍然埋頭去找派生類的vtable,發現根本沒有這個版本的虛函數,只好回頭調用自己的僅有一個虛函數。
 
這裏還值得一提的是:如果此時基類有多個虛函數,此時程序編繹時會提示調用不明確。示例如下
#include <iostream>
using namespace std;
 
class Base{
public:
         virtual void fun(int i){ cout <<"Base::fun(int i)"<< endl; }
               virtual void fun(char c){ cout <<"Base::fun(char c)"<< endl; }
};
 
class Derive : public Base{
public:
    void fun(double d){ cout <<"Derive::fun(double d)"<< endl; } 
};
 
int main()
{
         Base *pb = new Derive();
               pb->fun(0.01);//error C2668: 'fun' : ambiguous call to overloaded function
         delete pb;
         return 0;
}
好了,我們再來分析一下例8-2
n          8-2中,我們也爲派生類重載了一個函數版本:void fun(double d) ,同時覆蓋了基類的虛函數,我們再來具體來分析一下,基類共有幾個函數,派生類共有幾個函數:
類型
基類
派生類
Vtable部分
void fun(int i)
void fun(int i)
靜態部分
 
void fun(double d)
 
從表中我們可以看到,派生類的vtable中函數指針指向的是自己的重寫的虛函數地址。
 
我們再來分析一下以下三句代碼
 
Base *pb = new Derive();
pb->fun(1);//Derive::fun(int i)
pb->fun((double)0.01);//Derive::fun(int i)
 
第一句不必多說了,第二句,理所當然調用派生類的虛函數版本,第三句,嘿,感覺又怪怪的,其實呀,C++程序很笨的了,在運行時,埋頭闖進派生類的vtable表中(虛函數表virtual function table),隻眼一看,靠,競然沒有想要的版本,真是想不通,基類指針爲什麼不四處轉轉再找找呢?呵呵,原來是眼力有限,基類年紀這麼老了,想必肯定是老花了,它那雙眼睛看得到的僅是自己的非Vtable部分(即靜態部分)和自己要管理的Vtable部分,派生類的void fun(double d)那麼遠,看不到呀!再說了,派生類什麼都要管,難道派生類沒有自己的一點權力嗎?哎,不吵了,各自管自己的吧^_^
 
!你是不是要嘆氣了,基類指針能進行多態調用,但是始終不能進行派生類的重載調用啊(參考例6)~~~
再來看看例9,本例的效果同例6,異曲同工
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章