2011-12-25 72 views
-4

在下面的代碼中,我無法理解派生類的虛擬方法被調用的方式。 另外,任何人都可以提出一個資源,其中虛擬功能的概念用非常基本的方法進行圖解解釋。混淆派生類虛擬函數被調用的方式

class Base1 
{ 
    virtual void fun1() { cout << "Base1::fun1()" << endl; } 
    virtual void func1() { cout << "Base1::func1()" << endl; } 
}; 


class Base2 
{ 
    virtual void fun1() { cout << "Base2::fun1()" << endl; } 
    virtual void func1() { cout << "Base2::func1()" << endl; } 
}; 


class Base3 
{ 
    virtual void fun1() { cout << "Base3::fun1()" << endl; } 
    virtual void func1() { cout << "Base3::func1()" << endl; } 
}; 

class Derive : public Base1, public Base2, public Base3 
{ 

public: 

    virtual void Fn() 
    { 
    cout << "Derive::Fn" << endl; 
    } 

    virtual void Fnc() 
    { 
    cout << "Derive::Fnc" << endl; 
    } 
}; 


typedef void(*Fun)(void); 

int main() 
{ 
    Derive obj; 
    Fun pFun = NULL; 

    // calling 1st virtual function of Base1 
    pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+0); 
    pFun(); 

    // calling 2nd virtual function of Base1 
    pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+1); 
    pFun(); 

    // calling 1st virtual function of Base2 
    pFun = (Fun)*((int*)*(int*)((int*)&obj+1)+0); 

    pFun(); 

    // calling 2nd virtual function of Base2 

    pFun = (Fun)*((int*)*(int*)((int*)&obj+1)+1); 
    pFun(); 

    // calling 1st virtual function of Base3 
    pFun = (Fun)*((int*)*(int*)((int*)&obj+2)+0); 
    pFun(); 

    // calling 2nd virtual function of Base3 
    pFun = (Fun)*((int*)*(int*)((int*)&obj+2)+1); 

    pFun(); 

    // calling 1st virtual function of Drive 
    pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+2); 
    pFun(); 

    // calling 2nd virtual function of Drive 
    pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+3); 
    pFun(); 

    return 0; 
} 
+3

一切似乎是未定義行爲,所以沒有太多解釋。 – 2011-12-25 17:55:11

回答

5

的繼承圖看起來是這樣的:

Base1 Base2 Base3 

    \  | /
    \  | /
    \ | /
    \ | /

     Derived 

沒有明確的功能Derived::func1()。 Morover,virtual關鍵字是紅色的鯡魚,因爲Derived實際上並不重寫任何東西。所以唯一的問題是如何調用各種基本功能。具體方法如下:如果你是真正覆蓋func1()Derived

Derived x; 

// x.func1(); // Error: no unambiguous base function 

x.Base1::func1(); 
x.Base2::func1(); 
x.Base3::func1(); 

故事將是完全不同的。

0

你在顯示的代碼中所做的是使用「成員函數指針算術」來訪問基類的虛函數,由於它們奇怪的語法而且它們完全依賴於編譯器,因此它很醜陋。

我建議你閱讀這篇文章的快捷代表有多麼成員函數指針更深入的瞭解工作與問候到不同類型的遺產的:你做

http://www.codeproject.com/KB/cpp/FastDelegate.aspx

+0

它不只是「依賴於編譯器」;這是未定義的行爲。該標準不需要vtable。 – 2011-12-25 18:37:14

相關問題