我是其中一个必须使用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来关闭这个警告,但这不是我想在这里问的问题。我是否应该在这里听编译器,或者这只是一个非常过分热心的警告?
答案 0 :(得分:11)
执行虚拟继承时,不明确覆盖最派生类中的每个成员是一个坏主意。否则,当有人更改从虚拟基础继承的一个基类时,您要求您的代码死于可怕的死亡。这没有什么主动错误,你的程序不会崩溃或者是这样,但这是一个可维护性的坏主意。如果您想调用Bar::foo
版本,那么您应该在Quux::foo
中委托给它。
答案 1 :(得分:2)
就代码的可运行性而言,它只是提醒您Bar是foo
的主要实现。它只是告诉你,这不是一个警告,所以,如果你正在调试并认为它是Baz
,你就不要把头发拉出来。)。
答案 2 :(得分:1)
你有没有理由不写作:
class Quux : public Bar, public Baz
{
using Bar::foo;
};
这为您提供了相同级别的重用,没有脆弱性。