2014-11-03 78 views
1

如果C++中存在鑽石問題,如果Base和中等級別的類已經實現了虛函數。如何刪除給定的錯誤?實現虛函數的鑽石問題

#include <iostream> 

using namespace std; 

class Base 
{ 
    public: 
    virtual void display() 
    { 
     cout<<"In Base"<<endl; 
    } 
}; 

class Der1:virtual public Base 
{ 
public: 

    void display() 
    { 
    cout<<"In Der1"<<endl; 
    } 
}; 

class Der2:virtual public Base 
{ 
    public: 
    void display() 
    { 
     cout<<"In Der2"<<endl; 
    } 
}; 

class Mix: public Der1, public Der2 
{ 
}; 

int main() 
{ 
    cout << "Hello World!" << endl; 
    Mix m_mix; 
    m_mix.display(); 
    return 0; 
} 

我得到以下錯誤: -

main.cpp中:50:錯誤:請求爲成員 '顯示' 不明確 m_mix.display();

如何使用Mix類的對象訪問Der1和Der2的display()?

+0

*什麼*「虛擬」功能? – WhozCraig 2014-11-03 12:34:36

+0

'Mix'從兩個不同的類繼承'display'。沒有辦法確定應該調用哪一個。添加'使用Der1 :: display;','使用Der2 :: display;',或者覆蓋'Mix'中的'display'功能。 – 2014-11-03 12:38:06

+0

我不確定編輯display()虛擬是否有效。編譯錯誤清楚地表明它不是。 – Barry 2014-11-03 12:42:59

回答

1

要解決歧義,我們可以明確地指定的功能,例如:

m_mix.Der1::display(); 
1

首先,在你的代碼是沒有virtual功能。但是,如果有的話,這並不重要。 (更新:想想吧,如果display()虛擬然後Mix作爲一個類不會編譯,因爲哪個函數你放在vtable?你會得到一個錯誤,甚至沒有呼籲display())。

當您撥打Mix::display()時,有兩種選擇:Der1::display()Der2::display()。編譯器不可能區分它們,所以不是試圖猜測你想要什麼,而是告訴你它不能。所以你就必須要明確:

m_mix.Der1::display(); 

static_cast<Der1&>(m_mix).display(); 

或寫Mix::display()功能,做什麼是你想做的事情。

+0

我試過m_mix.Der1 :: display(),我得到以下錯誤:如果我不在Mix類中重寫display(),那麼在'Mix'中'virtual void Base :: display()'沒有唯一的最終覆蓋那麼是否有必要這樣做? – learner 2014-11-03 13:01:37

+0

@learner這與您最初發布的問題不同。在那裏,你需要一個獨特的覆蓋'display()',你有兩個。所以你需要提供一個'Mix :: display()'覆蓋來編譯它。 – Barry 2014-11-03 13:35:22

0

呼叫這樣的: -

m_mix.Der1::display(); 

OR

m_mix.Der2::display(); 
+0

我得到以下錯誤:如果我不覆蓋Mix類中的display(),那麼'混合' 中'virtual void Base :: display()'沒有唯一的最終覆蓋。是否有必要這樣做? – learner 2014-11-03 12:50:57

0

在中間水平虛繼承只是確保在最後一級基類不包含兩次,但是,因爲任何個人Der1Der2都有自己的display(),編譯器將這兩個函數成員添加到Mix。如果您不想在Der1Der2中重新定義display,您的示例將會有效。它與virtual-display()無關。例如,該代碼按預期工作:

#include <iostream> 

using namespace std; 

class Base 
{ 
public: 
    void display() 
    { 
     cout << "In Base" << endl; 
    } 
}; 

class Der1: virtual public Base 
{ 
public: 

    /* void display() 
    { 
     cout<<"In Der1"<<endl; 
    }*/ 
}; 

class Der2: virtual public Base 
{ 
public: 
    /* void display() 
     { 
      cout<<"In Der2"<<endl; 
     }*/ 
}; 

class Mix: public Der1, public Der2 
{ 
}; 

int main() 
{ 
    cout << "Hello World!" << endl; 
    Mix m_mix; 
    m_mix.display(); 
    return 0; 
} 
0

我在你的代碼發現另一個錯誤:類混合錯誤:虛函數「基地::顯示」的覆蓋是模糊的。這是因爲在你的基類void display()中是虛擬的

class Base 
{ 
    public: 
    virtual void display() 
    { 
     cout<<"In Base"<<endl; 
    } 
}; 

因此,在類Mix中應該有一個void display()的實現。

class Mix: public Der1, public Der2 
{ 
    // need to implement void display() 
};