【问题标题】:Inheritance by dominance - is it really bad?支配继承——真的很糟糕吗?
【发布时间】:2011-10-27 15:38:50
【问题描述】:

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

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

【问题讨论】:

  • 老实说,在我看来,使用虚拟继承是糟糕的设计。它太复杂了,收益很少。在使用它之前,我会认真三思而后行。
  • 代码可能还不错,但很脆弱。依靠晦涩的消歧规则来选择要调用的函数不会使代码非常易于阅读或维护。
  • @PeterAlexander "太复杂了" 怎么复杂?

标签: c++ visual-c++ diamond-problem


【解决方案1】:

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

【讨论】:

  • 我认为这是一个很好的观点。将所有内容移至派生最多的类(当然,上面是一个简化的示例)并不完全适合我的实际问题,因此我可能必须仔细检查我的整体设计。 (我确实希望 Bar 类的用户。)
  • 废话。仅仅因为你不练习某事并不会使它变得不健全/糟糕/无论如何。只需说:“我不习惯这样。”
  • @curiousguy:我从来没有说过我不练习它,我给出了一个很好的理由说明它为什么不好。如果你想暗示我错了,那就给一个客观的理由,说明它还不错。
  • "死得很惨" 可怕的死 = 每当你引入歧义时的编译器消息。可怕,确实。 (笑)
  • 其实在这种情况下,虚函数表会发生什么? foo() 有 1 个条目还是 2 个条目?如果只有一个条目并且 foo() 在 Bar 和 Baz 中都被覆盖,那会对 final 类的虚拟函数表有什么影响?
【解决方案2】:

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

【讨论】:

  • 就个人而言,至少,我将 4 级警告视为“只是为了通知您”。 2 级(这是)似乎更符合“你在这里做什么......”。 (作为比较:C4390 是 3 级,这通常很糟糕。)
  • 我会对一个编译器感兴趣,它可以告诉我用于编译程序的每条非显而易见的 C++ 规则。对于每个重载的函数调用,大约有 5 条消息;对于重载决议调用的每个内置运算符;将有 15 条消息;对于每个模板重载函数调用,将有 30 条消息。编译日志会比程序源代码大很多。
【解决方案3】:

你不写有什么原因吗:

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

?

这为您提供了相同水平的重用,没有脆弱性。

【讨论】:

  • 它没有帮助。无论如何它都会发出警告。 VC++ 2013
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多