#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::methodn";
};
};
int main(int argc,char *argv[])
{
D d;
B1 &b1=d;
B2 &b2=d;
b1.method();
b2.method();
return 0;
}
请注意,B1 和 B2 不共享公共接口。
这合法吗?如果是 - 在哪个标准中?C++11-03-98 ?
msvc 和 gcc 都编译好了。
以前我认为,在这种情况下,我必须使用一些通用接口(可能的虚拟继承(。
这种情况有什么特殊的名字吗?
请问它是如何详细工作的?也许一些ISO参考?
您的代码格式正确:void D::method()
会覆盖void B1::method()
和void B2::method()
。
规范指出 (C++11 §10.3/2(:
如果一个虚成员函数
vf
是在类Base
和类Derived
中声明的,直接或间接地从Base
派生,一个成员函数vf
与声明Base::vf
具有相同的名称、参数类型列表、cv-限定符和ref限定符(或没有相同(,那么Derived::vf
也是虚拟的(无论它是否如此声明(,并且它覆盖Base::vf
。
B1
声明一个虚拟成员函数void B1::method()
。 类 D
派生自 B1
,它还声明了一个具有相同名称 (method
(、相同参数列表(无参数(、相同 cv 限定符(无限定(和相同 ref 限定符(无限定(的成员函数。
因此,void D::method()
将覆盖void B1::method()
。
同样的逻辑也适用于void B2::method()
(只是在上面的解释中用B2
代替B1
(,所以void D::method()
覆盖了void B1::method()
和void B2::method()
。
afaik 这在每个标准中都是合法的。 我不确定它是否有自己的特殊名称,但它类似于钻石问题。
如果覆盖 D 中的"虚拟 void method((",则覆盖 B1 和 B2 中的方法。
编辑:
为什么你没有"D中两个不同的独立继承虚函数:B1::方法和B2::method":
重写方法时,只能指定函数名称、返回类型和参数,但不能添加有关重写时继承自哪个方法的签名详细信息。
想象一下这是可能的,那么它可能看起来像这样:
struct D: B1, B2
{
virtual void B1::method()
{
std::cout << "D::methodn";
};
virtual void B2::method()
{
std::cout << "D::methodn";
};
};
但是看到这个,你已经可以说不可能有这样的事情了,因为在打电话时
objectD.method()
您不能指定要调用哪一个。 因此,即使有一种方法可以重载两者,仍然存在区分函数调用的问题。
编辑:"不能指定你调用的是哪一个"指的是,你不能指定是要调用 B2::method 的 D 类重载还是 B2 方法本身。objectD.B2::method将始终调用B2(未重载(方法(在这种情况下,由于B2没有实现,因此不会编译(