显性遗传真的很糟糕吗?

Inheritance by dominance - is it really bad?

本文关键字:真的      更新时间:2023-10-16

我是那些不得不让自己的代码编译为0警告的人之一。通常情况下,我尊重编译器,如果它给我一个警告,我把它作为一个信号,我应该润色一下我的代码。如果我必须告诉编译器忽略给定的警告,我会抽搐一下。

但这一个我似乎无法绕过,从我可以告诉我,我没有做任何"坏事"。有人认为这是一个糟糕的设计吗?我看不出它有什么特别令人讨厌的地方(除了"邪恶的钻石"),但它是完全有效和有用的代码。但是它生成(在MSVC中)一个2级警告!

class IFoo
{
public:
    virtual void foo() = 0;
};
class Bar : public virtual IFoo
{
public:
    virtual void foo() { std::cout << "Hello, world!"; }
};
class Baz : public virtual IFoo
{
};
class Quux : public Bar, public Baz
{
};

现在,如果我创建一个Quux对象,它应该会调用Bar::foo实现。MSVC非常有用:它会警告我不够模棱两可。

警告C4250: 'Quux':通过支配继承'Bar::Bar::foo'

现在我知道我可以用一个pragma关闭这个警告,但这不是我在这里要问的问题。我在这里应该听编译器的吗,或者这只是一个过分的警告?

在执行虚拟继承时,不显式覆盖最派生类中的每个成员是一个坏主意。否则,当有人更改了从虚拟基类继承的基类之一时,您的代码将面临可怕的死亡。这并没有什么主动的问题,你的程序不会崩溃或诸如此类,但这是一个可维护性不好的主意。如果您想调用Bar::foo版本,那么您应该在Quux::foo中委托给它。

就代码的可运行性而言,它只是提醒您Bar是foo的主要实现。它只是在那里告诉你,它不是一个真正的警告,所以如果你正在调试并认为它是Baz,你不要拔你的头发:)。

你为什么不写呢?

class Quux : public Bar, public Baz
{
    using Bar::foo;
};

?

这给了您相同级别的重用,而没有脆弱性。