2011-04-05 53 views
3

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

请参阅以下示例代码示例:

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

这些函数有不同的签名(一个接受一个int,一个接受一个float),因此它们并不是真正的“相同”。

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

编辑:好的,让我解决实际问题(如您的评论中所述)。从技术上讲,它仍然不含糊:InheritFrom的每个版本都有自己的vtable,并且MultipleInheritor有一个vtable。您可以选择范围sharedMethod(如InheritFrom<int>::sharedMethod())的任何父代执行的范围,但就呼叫方而言,您的MultipleInheritor类型的对象有一个虚拟表,其中有一个条目sharedMethod

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

+0

对不起,如果代码示例不是100%清楚,我实际上是指sharedMethod()不是doSomething()是我的问题的对象。 – radman 2011-04-05 01:01:36

+0

对不起!编辑它,虽然我不像我原来的回应那样确定。尽管如此,这应该包括它。 – EboMike 2011-04-05 01:06:02

+0

你的答案是我认为它必须工作的方式(鉴于代码编译和工作),我真的希望确认这种情况,并且没有任何诡计正在进行。 – radman 2011-04-05 01:25:10

1

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

了Bjarne Stroustrup的描述的一个可能的实现MI的虚函数在这里:Multiple Inheritance for C++

基本上InheritFrom<int>虚函数表和InheritFrom<float>虚函数表的MultipleInheritor得到修改,以便为sharedMethodMultipleInheritor::sharedMethod两个条目。

+0

感谢您的链接,这是一个有趣的阅读。 – radman 2011-04-05 03:23:15