具有冲突方法的多重继承

时间:2011-04-05 00:37:22

标签: c++ templates inheritance

我正在编写一些模板化的纯虚拟基类,它们是多重继承的,并且在这个过程中发现了一个小小的奇怪现象。它的关键是,如果你在两个基类中定义相同的方法,继承两个编译并且工作正常,看起来你只需要派生类中的单个定义。我很好奇这里幕后发生了什么,这是正确的,有计划的行为还是危险的编译器疏忽?

请参阅下面的示例代码示例:

namespace
{
  template <typename T_NumType>
  class InheritFrom
  {
  public:
    virtual void doSomething(const T_NumType& numType) = 0;

    virtual void sharedMethod() = 0;

  }; // class

  class MultipleInheritor : public InheritFrom<int>, public InheritFrom<float>
  {
  public:
    void doSomething(const int& numType) {}
    void doSomething(const float& numType) {}

    void sharedMethod() {} // one definition here

  }; // class

}

int main(int argc, char** argv)
{
  MultipleInheritor mult;
  mult.doSomething(5);
  mult.sharedMethod();

}

编辑:
下面的答案和查看C ++ 98标准最终为我解决了这个问题。

从10.3开始:虚函数:

  

在任何格式良好的班级中,每个班级   在那里声明的虚函数   类或其任何直接或间接的   基类有一个独特的决赛   覆盖该功能的覆盖   以及其他所有的重写   功能

所以这意味着对于任何虚拟功能,都会找到一个最终覆盖。这是通过10.2:成员名称查找中详述的规则完成的。

因此,在我提出的情况下,确实存在两个基类函数,并且由于成员名称查找,派生类中的单个函数被确定为两者的最终覆盖。所以我所拥有的非常完美,并且是C ++编译器工作的合理结果。

2 个答案:

答案 0 :(得分:2)

这些函数有不同的签名(一个采用int,一个采用浮点数),因此实际上并不是“相同”。

模板魔术模糊了一点,但它与foo(int)foo(float)相同 - 这是两个不同的功能。您可以拥有foo(int) constfoo(int),这也是两个不同的功能。

编辑:好的,让我解决一下实际问题(如评论中所述)。从技术上讲,它仍然没有含糊不清:InheritFrom的每个版本都有自己的vtable,MultipleInheritor有一个vtable。您可以选择sharedMethod的任何父实现的范围(如InheritFrom<int>::sharedMethod()),但就调用者而言,类型为MultipleInheritor的对象有一个vtable,其中一个条目为{{ 1}}。

编辑编辑:关键是你在子类中实现sharedMethod。如果它不是纯粹的并且在sharedMethod中没有实现,则会出现编译器错误,因为它不清楚将什么放入vtable中的一个插槽中。

答案 1 :(得分:1)

在派生类中用一个函数定义覆盖两个同名的虚函数是C ++中多重继承的一个特性。

Bjarne Stroustrup在此描述了使用虚拟函数实现MI的一种可能方式:Multiple Inheritance for C++

基本上InheritFrom<int> vtable和InheritFrom<float> vtable MultipleInheritor会被修改,以便sharedMethod的两个条目都指向MultipleInheritor::sharedMethod