【问题标题】:C++ Multiple and virtual inheritanceC++ 多重继承和虚拟继承
【发布时间】:2014-01-17 09:19:36
【问题描述】:

我正在尝试实现以下类:

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(...)
{
}

这对我来说似乎不合逻辑,因为 'd' 继承自 'c' 和 'b' 将首先构造。

【问题讨论】:

    标签: c++ inheritance virtual


    【解决方案1】:

    构造或声明的顺序无关紧要。如果有 2 个基类具有相同的方法名称,编译器将无法判断您要调用哪一个。在您的情况下,您在 b 类和 d 类中都有 f() 的覆盖版本。

    所以要明确地调用。 b::f() 或 d::f()。

    【讨论】:

      【解决方案2】:

      e 是从 b & d 继承的,所以有 f() 的 b 版本和 f() 的 d 版本。

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

      如果想让e类使用d版本的f(),有两种方法,

      1. 在调用中直接调用d::f()

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

      2. 在 e 中重新声明 d::f()

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

      我不明白你为什么在这里提到构造函数,构造顺序对函数 f() 没有影响。

      【讨论】:

      • +1 - using d::f; 是一个不错的选择。第三种方法是将void f() { d::f(); } 添加到class e - 这里不是必需的,但有时在修改参数、添加日志等时很有用。
      • 这只是因为我不明白为什么编译器要我以这个特定的顺序构建构造函数,因为在我看来,b 是首先构建的。不过谢谢你的回答,我会使用“使用”的方法。
      猜你喜欢
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 2014-11-06
      • 2014-10-12
      • 2015-11-21
      • 2010-09-22
      • 2016-03-26
      • 2011-01-08
      相关资源
      最近更新 更多