多重继承来解决抽象类

时间:2012-07-06 17:23:08

标签: c++ multiple-inheritance

说我有4节课:

class I { public: virtual void X() = 0; };
class A : public virtual I { public: virtual void X() { } };
class B : public I {  };
class C : public A, public B { };

IBC是抽象的,而A则不是。{1}}。如果我只是将virtual添加到I B的继承,那么A::X()会在I::X()中解析C

但是,我无法更改B的来源。

我的问题:我是否可以A::X()解析I::X C而无法更改B?我已尝试将AB声明为C虚拟无效。我试图没有冗余代码(例如,有C声明X(){A :: X();})。任何整洁的黑客?

此外 - 有一些非常类似的问题,但我找不到任何关于使用virtual继承的讨论。如果我错过了,请指点我。

3 个答案:

答案 0 :(得分:3)

你的问题在于vtables。在您当前的代码中,您有两个 - 一个在A的{​​{1}}中,另一个在I的{​​{1}}中。只要B实际上只继承I,您就可以使用常规继承并节省开销。如果两者都是虚拟继承A,那么I中只有一个I个实例,因此只有一个vtable,而I确实可以覆盖纯C A::X }。

鉴于您无法更改I::X,您唯一可以处理这两个vtable的地方是B。在我看来,你要提到的方法是 - 只需要C将呼叫转发给C::X。那里没有代码重复,它使A::X非抽象:

C

至于虚拟继承,肯定有have been some here。但是欢迎你问...

答案 1 :(得分:2)

这非常好:When virtual inheritance IS a good design?

这里的问题是在C中你有两个接口I.这就是A :: x()满足的原因 它的接口我 - 但它不能使B类中的抽象接口不能生成。 对于C来说,只有一个I接口的唯一方法是将B改为从虚拟中导出 - 这样来自A和B的I接口将合并为C中的一个。你不能改变B - 所以唯一方法是添加您要避免的冗余代码。我的意思是定义C :: X()。

答案 2 :(得分:1)

我能想到的唯一方法是将B*(或智能变体)组合成C而不是继承它,并转发适当的方法。在维护继承时不能这样做,因为编译器不知道要跟随哪个I的继承链。