霸权继承——真的很糟糕吗?
我是那些必须在 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”
现在我认识到我可以使用编译指示关闭此警告,但这不是我在这里想问的问题。我是否有理由应该在这里听编译器的声音,或者这只是一个极其过分的警告?
I'm one of those people that has to get their code to compile with 0 warnings. Normally I respect the compiler and if it issues me a warning I take it as a sign that I should touch up my code a little. If I have to tell a compiler to ignore a given warning, I twitch a little.
But this one I can't seem to get around, and from what I can tell I haven't done anything "bad". Does anyone think that this is a poor design? I can't see anything particularly nasty about it (except for the "evil diamond") but it's perfectly valid and useful code. But it generates (in MSVC) a level 2 warning!
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
{
};
Now if I create a Quux object it should be expected to call the Bar::foo implementation. MSVC is very helpful: it warns me for not being ambiguous enough?
warning C4250: 'Quux' : inherits 'Bar::Bar::foo' via dominance
Now I recognize I can turn this warning off with a pragma, but that's not the question I'm trying to ask here. Is there a reason I should be listening to the compiler here, or is this just an extremely overzealous warning?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
执行虚拟继承时,不显式重写最派生类中的每个成员是一个坏主意。否则,当有人更改从虚拟基继承的基类之一时,您就会要求您的代码惨遭死亡。这没有什么积极的错误,你的程序不会崩溃或任何类似的事情,但这是一个可维护性的坏主意。如果您想调用
Bar::foo
版本,那么您应该在Quux::foo
中委托给它。When performing virtual inheritance, it is a bad idea to not explicitly override every member in the most derived class. Else, you are asking for your code to die a horrible death when someone changes one of your base classes that inherits from the virtual base. There's nothing actively wrong with this, your program won't crash or anysuch, but it's a maintainability bad idea. If you want to call the
Bar::foo
version, then you should just delegate to it inQuux::foo
.就代码的可运行性而言,它只是提醒您 Bar 是
foo
的主要实现。它只是通知您,并不是真正的警告,因此,如果您在调试时认为是Baz
,您就不会感到惊慌:)。As far as the runability of your code is concerned, it is just there to remind you that Bar is the dominant implementation of
foo
. It is just there to inform you, it's not really a warning, so that if you're debugging and think it'sBaz
you don't pull your hair out :).你有没有理由不写:
?
这为您提供了相同级别的重用性,而没有脆弱性。
Is there a reason you aren't writing:
?
This gives you the same level of reuse, without the fragility.