霸权继承——真的很糟糕吗?

发布于 2024-11-29 21:06:30 字数 707 浏览 1 评论 0原文

我是那些必须在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦里梦着梦中梦 2024-12-06 21:06:30

执行虚拟继承时,不显式重写最派生类中的每个成员是一个坏主意。否则,当有人更改从虚拟基继承的基类之一时,您就会要求您的代码惨遭死亡。这没有什么积极的错误,你的程序不会崩溃或任何类似的事情,但这是一个可维护性的坏主意。如果您想调用 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 in Quux::foo.

流星番茄 2024-12-06 21:06:30

就代码的可运行性而言,它只是提醒您 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's Baz you don't pull your hair out :).

ぇ气 2024-12-06 21:06:30

你有没有理由不写:

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

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

Is there a reason you aren't writing:

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

?

This gives you the same level of reuse, without the fragility.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文