#include<iostream>
using namespace std;
class base
{
public:
virtual void f(){}
};
class middle1:public base
{};
class middle2:public base
{};
class derive:public middle1,public middle2
{};
int main()
{
derive* pd=new derive();
pd->f();
return 0;
}
我知道虚拟解决了这个问题,但是如何解决? 即使我们没有多重继承,我们是否可以始终将公共虚拟写入安全性。
答案 0 :(得分:2)
derive
的每个实例都有一个middle1
基类子对象和一个middle2
基类子对象。
如果继承是非虚拟的,那么middle1
基类子对象有一个base
基类子对象,和 middle2
基类子对象还有一个base
基类子对象。因此,derive
的每个实例都有两个base
个子对象,而调用pd->f()
是不明确的 - 您要调用哪个base
个对象{{1在?
使继承成为虚拟意味着f()
和middle1
将共享middle2
个base
个子对象。这消除了歧义 - 只有一个derive
对象可以调用base
。
我们是否可以始终将公共虚拟写入安全
不一定。可能存在继承层次结构,您不希望 {/ em> f()
和middle1
共享公共middle2
子对象。您可能会争辩说,在这种情况下,您不应该编写继承自两者的类base
,但如果您最终遇到这种情况,则解决方法是执行以下任一操作:
derive
指定要在static_cast<middle1*>(pd)->f();
pd->middle1::f();
基类子对象上调用f
,或
middle1
指定static_cast<middle2*>(pd)->f();
pd->middle2::f();
。
答案 1 :(得分:1)
我知道虚拟解决了这个问题,但是如何解决?
virtual
个关键字通过在继承层次结构中只存在一个顶级基类子对象来解决问题。没有它,每个父类middle1
&amp; middle2
拥有自己的base
类副本,因此导致含糊不清。
即使我们没有多重继承,我们是否可以始终将公共虚拟写入安全性。
如果没有多重继承,则没有理由使用virtual
继承。多重继承是存在虚拟继承概念的目的。
答案 2 :(得分:1)