手头的问题很难描述,所以代码被放在前面以获得更好的清晰度。多继承虚拟呼叫模糊
struct Base
{
int b;
virtual void foo(){cout << b << endl;}
Base(int x) : b(x){}
};
struct Derived1 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived1() : Base(1){}
};
struct Derived2 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived2() : Base(2){}
};
struct MultiInheritance : Derived1, Derived2
{
void bar1()
{
//needs to access Derived1's Base foo()
}
void bar2()
{
//needs to access Derived2's Base foo()
}
};
假设在有些怪异离奇的情况下,我想一个基类MultiInheritance
有两个基类Derived1
和Derived2
有一个共同的非虚基类Base
。
有两个Base
在MultiInheritance
,我怎么指定我想在MultiInheritance
访问哪些Base
类?
上面的代码似乎很好地通过投射多次,但我不知道这是否定义的行为。如果是这样,编译器如何实现它以满足多态性的需求?一方面virtual
调用应该都产生相同的virtual
函数表,但另一方面,如果它不会输出不同的答案。
编辑
我想强调的是,Base
类必须是非虚拟
EDIT2
深深的歉意,我严重歪曲了自己。上面的代码更新更好地反映了我原来的问题。
哪一个你认为的正确* *'Base'?或者是你的问题如何使它只有一个'Base'? – Barry
你的分析是正确的,编译器会建立一个反映两个基类存在的正确的vtable。为了避免这种情况,您需要虚拟继承,并且vtable结构将变得更加复杂。 –
您的示例中没有任何歧义,它的行为与书中的完全相同。 “虚拟表”是一个实现细节。没有人在任何地方说每个实现必须每个类有一个vtbl,或者每个vtable中的每个函数签名都必须有一个条目。实际上,对于使用vtables的任何实现来说,上述至少一个是不正确的。 –