【问题标题】:Multiple inheritance to solve abstract classes多重继承解决抽象类
【发布时间】:2012-07-06 17:23:07
【问题描述】:

假设我有 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 不是。如果我只是简单地将virtual 添加到I 的继承中以获得B,那么A::X()C 中解析I::X()

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

我的问题:我能否让A::X()C 解析I::X 而不能更改B?我尝试将 AB 声明为虚拟到 C 无济于事。我试图没有多余的代码(例如让 C 声明 X() { A::X(); })。有什么巧妙的技巧吗?

另外 - 有几个问题非常像这样,但我找不到任何关于使用 virtual 继承的讨论。如果我错过了,请指点给我。

【问题讨论】:

    标签: c++ multiple-inheritance


    【解决方案1】:

    您的问题出在 vtables 上。在您当前的代码中,您有两个——一个在AI 中,一个在BI 中。只要只有A 虚拟继承I,您也可以使用常规继承并节省开销。如果两者都虚拟继承I,那么C 中只有一个I 实例,因此只有一个vtable,A::X 确实可以覆盖纯虚拟I::X

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

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

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

    【讨论】:

    • 非常感谢您的解释,谢谢。此外,相关问题的“智能”链接也有一些亮点。我会选择 PiotrNycz 的答案 - 部分原因是新人可以使用更多的声誉:) - 你们都给出了我需要的答案。再次感谢您。
    【解决方案2】:

    这个不错:When virtual inheritance IS a good design?

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

    【讨论】:

    • 我希望不必定义 C::X,但这似乎是共识。谢谢。
    【解决方案3】:

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

    【讨论】:

    • 有趣的想法(指向“整洁的黑客”)我没有在问题中提到,但我需要将 C 公开为 B*,所以这不起作用。不过谢谢你的建议。
    • 您实际上可以通过从B 继承来做到这一点。如果你在C 中实现X,它将作为X 在两个基中的最终覆盖。
    猜你喜欢
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多