【问题标题】:Is declaring a class in C++ as "final : public virtual" EVER useful?将 C++ 中的类声明为“final:public virtual”有用吗?
【发布时间】:2018-07-03 13:44:57
【问题描述】:

当将 c++ 类声明为 final 时,是否需要使用虚拟继承来继承基类?我知道虚拟继承的用途并使用它来避免成员重复。

例如,如果我有这些类定义(想象它们都有一些成员和虚拟解构器)

class B : public virtual A {};
class C : public virtual A {};
class D : public virtual C {};

定义下一个类是否有意义

class E final : public virtual D {}

class F final : public virtual B, public virtual C {};

或者是默认继承,即

class E final : public D {}
class F final : public B, public C {};

总是够了吗?

这已经困扰了我很长时间,正如我不时看到的代码,其中包括

"final : public virtual"

virtual任何情况下可以安全地省略吗?

非常感谢任何提示/解释

【问题讨论】:

  • 由于虚拟继承允许共享基类(即只有一次实例),而final用于标记一个类不允许派生......这两件事是彼此独立。如果删除虚拟,则不再共享基类。只关心多重继承。
  • 您能否提供一个(多重继承)示例,其中省略virtual 真的会产生影响?
  • en.wikipedia.org/wiki/Virtual_inheritance 有一个例子。想象一下 struct Bat final : Mammal, WingedAnimal, virtual Animal 被更改为 struct Bat final : Mammal, WingedAnimal, Animal ...哎呀,bat.eat() 变得模棱两可。
  • @Eljay "只关心多重继承。" 不完全是。 Virtual 模糊了直接基类和间接基类之间的区别。

标签: c++ inheritance virtual final virtual-inheritance


【解决方案1】:
struct A { void foo() { cout << "foo" << endl; } };
struct B : virtual A {};
struct D final : virtual A, B {};

D d;
d.foo();

A 之前没有virtual 调用foo 将是模棱两可的。

【讨论】:

  • 完美。这意味着当使用多重继承时,虚拟可能总是被省略?
  • @Ironbell 是的,virtual 在这种情况下是为了处理钻石问题而添加的。
  • @Ironbell • 在我从事的生产C++ 代码中,我从未发现需要对具体基类或抽象基类进行多重继承。我使用多重继承来拥有一个且只有一个具体或抽象的基类和多个接口类。 (C++ 没有通过 interface 关键字来强制约束,所以它只是按照惯例和纪律。)
  • @Eljay 这不是关于是否以及何时使用 MI 的问题,而是这种组合是否有用的问题。对于 MI,好吧,一种尺寸并不适合所有人。感谢您的回答,遗憾的是,我还没有足够的代表来支持 cmets。
  • "对 foo 的调用会模棱两可" 不仅如此(备注不适用于您的简单示例,其中A 没有状态,也没有构造函数可以做很多事情)没有虚拟,你甚至不能写一个构造函数来初始化基类子对象A
猜你喜欢
  • 1970-01-01
  • 2014-01-01
  • 2010-12-28
  • 1970-01-01
  • 2017-04-11
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
相关资源
最近更新 更多