覆盖基类的虚函数,它们不共享公共接口

时间:2012-07-12 19:45:13

标签: c++ override virtual multiple-inheritance

#include <iostream>
struct B1
{
    virtual void method()=0;
    virtual ~B1(){}
};

struct B2
{
    virtual void method()=0;
    virtual ~B2(){}
};

struct D: B1, B2
{
    virtual void method()
    {
        std::cout << "D::method\n";
    };
};

int main(int argc,char *argv[])
{
    D d;
    B1 &b1=d;
    B2 &b2=d;
    b1.method();
    b2.method();
    return 0;
}

注意,B1和B2不共享通用接口。

这是合法的吗?如果是 - 在哪个标准? C ++ 98/03/11?

两者,msvc和gcc编译好了。

以前我认为,我必须使用一些通用接口来处理这种情况(可能的虚拟继承)。

这种情况有什么特别的名字吗?

请问详情如何?也许一些ISO参考?

2 个答案:

答案 0 :(得分:7)

您的代码格式正确:void D::method()会覆盖void B1::method()void B2::method()

规范陈述(C ++11§10.3/ 2):

  

如果在类vf和类Base中声明虚拟成员函数Derived,直接或间接地从Base派生,则成员函数{{1声明同名,参数类型列表,cv-qualification和ref-qualifier(或缺少相同),vf也是虚拟的(无论是否为如此声明)并覆盖Base::vf

Derived::vf声明虚拟成员函数Base::vf。类B1派生自void B1::method(),它还声明了一个具有相同名称(D),相同参数列表(无参数),相同cv资格(无资格)的成员函数)和相同的参考资格(没有资格)。

因此,B1会覆盖method

同样的逻辑适用于void D::method()(在上述说明中仅用void B1::method()代替void B2::method()),因此B2会覆盖B1和{{1} }}

答案 1 :(得分:1)

afaik这在每个标准中都是合法的。我不确定它是否有自己的特殊名称,但它与diamond problem类似。

如果在D中覆盖“virtual void method()”,则覆盖B1和B2中的方法。

修改

向anwser说明为什么你没有“D:B1 :: method和B2 :: method”中的“两个不同的独立继承虚函数”:

当覆盖方法时,您只能指定函数名称,返回类型和参数,但是无法在覆盖时添加有关从哪一个继承的签名详细信息。

想象一下它是可能的,那么它看起来像这样:

struct D: B1, B2
{
    virtual void B1::method()
    {
        std::cout << "D::method\n";
    };
    virtual void B2::method()
    {
        std::cout << "D::method\n";
    };
};

看到这一点,你已经可以说没有可能有这样的东西了,因为在打电话时

objectD.method()

您无法指定要呼叫的是哪一个。因此,即使有两种方法都要超载,仍然存在区分函数调用的问题。

修改 “无法指定你打电话给哪一个。”指的是,你不能指定是否要调用B2 :: method的D类重载或B2方法本身。 objectD.B2 ::方法将始终调用B2(不重载)方法(在这种情况下不会编译,因为B2没有实现)