2014-01-17 32 views
2

我试图实现以下类:C++多重和虚拟继承

class a { 
public : 
    //... 
    f(); 
    //... 
}; 

class b : virtual public a { 
public : 
    //... 
    f(); 
    //... 
} 

class c : virtual public a { 
public : 
    //... 
    f(); 
    //... 
} 

class d : virtual public c { 
public : 
    //... 
    f(); 
    //... 
} 

class e : public b, public d { 
public : 
    //... 
} 

但是编译器告诉我,为成员函数f()的要求是不明确的。 我想'e'继承'd'的f()版本(所以'c'),但只有在'e'中重新声明f()时才会编译代码。所以,我只能编译如果我如下的代码“E”的构造函数:

e::e(...) : a(...), c(...), b(...), d(...) 
{ 
} 

这似乎不合逻辑对我来说,因为从“C”“d” inherate和“b”将首先建造。

回答

1

e为从B & d继承,所以公司的F B版()和f的d()版本。

这是非常合乎逻辑的,有歧义。

如果你想E级使用F(d的版本),有两种方法,

  1. 调用d :: f()的直接调用

    instance_e.d::f(); //will call d::f().

  2. 重新声明d :: f()的在电子

    class e : public b, public d { public : using d::f; }

我不明白你为什么在这里提到的构造,敷设渠道的订单有没有影响到函数f()。

+0

+1 - '用d :: F;'是一个不错的选择。第三种方法是添加'void f(){d :: f(); }'to'class e' - 在这里没有必要,但有时在修改参数时有用,记录添加等等。 –

+0

这只是因为我不会不确定编译器为什么要按照特定的顺序构建构造函数,因为,在我看来,b是要先建成的。谢谢你的回答,但我会使用'使用'方法。 – Kernael

2

它不与建筑或声明的顺序关系。如果有两个基类具有相同的方法名称,编译器无法确定您打算调用哪一个。在你的情况下,你在类b和类d中都有一个被覆盖的f()的版本。

于是拨打电话明确。 b :: f()或d :: f()。