【问题标题】:2 ways of resolving ambigous inheritance of virtual method解决虚方法二义性继承的2种方法
【发布时间】:2019-10-23 14:11:33
【问题描述】:

以下代码来自MSDN,我复制了这里的代码以避免自己做示例,基本上我的项目中遇到了这个问题。

struct V {
   virtual void vf();
};

struct A : virtual V {
   void vf() override;
};

struct B : virtual V {
   void vf() override;
};

struct D : A, B {
   // Uncomment the following line to resolve.
   // void vf() override;
};

我查看了这个SO Question,其中建议使用using 指令来解决不明确的符号。

该建议不适用于此示例,而是要解决我们应该显式覆盖派生类中的基方法的问题。

我想避免在派生类中显式覆盖,所以问题是,为什么不能使用上面 SO 链接中建议的 using 指令解决这个问题,而不是覆盖?例如:

struct D : A, B {
   using A::vf(); // not going to work
};

避免显式覆盖的原因是在其中一个基类中使用方法代码。

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    在你的情况下,我认为你必须给出明确的覆盖来解决歧义!但是,这将是一个极其微不足道的覆盖:

    struct D : A, B {
        // Uncomment the following line to resolve.
        void vf() override { A::vf(); }
    };
    

    每当调用D::vf() 时,这只会调用A 基类!因此,按照您的最后一句话,没有问题,因为使用了“基类之一中的方法代码”(但您必须指定哪个基类)。

    【讨论】:

    • 请注意:我通常不习惯在答案中使用“我认为”这个短语:在这种情况下,我的意思是,据我所知,没有办法避免这种覆盖。但是,我很想看看这个论坛上是否有任何非常体面的c++ 编码人员可以想出一种方法来避免它。
    【解决方案2】:

    using 在这种情况下仅解析您要调用的方法。
    D 仍然需要是一个完整的对象,并且必须有一个用于 vf 的最终覆盖器,而不管解析助手如何。
    如果vf 没有在基类中实现,那么using 就足够了,因为类型是完整的,您需要做的就是解析正确的调用。

    【讨论】:

    • 附加说明:vf() 是虚拟的,因此需要区分vf() 的实现最终在D 的vtable 中。像 using 这样的指令并非旨在影响 vtable 无法达到目的。
    猜你喜欢
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    相关资源
    最近更新 更多