22

我是那些必须让他们的代码以 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'

现在我认识到我可以用编译指示关闭这个警告,但这不是我想在这里问的问题。有什么理由我应该在这里听编译器,还是这只是一个非常过分热心的警告?

4

3 回答 3

12

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

于 2011-08-15T22:47:43.070 回答
2

就代码的可运行性而言,它只是提醒您 Bar 是foo. 它只是为了通知您,并不是真正的警告,因此如果您正在调试并认为这是Baz您的问题,请不要拉扯头发:)。

于 2011-08-15T22:47:55.833 回答
1

你不写有什么原因吗:

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

?

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

于 2011-11-23T05:22:35.327 回答