2014-11-03 57 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() 
};