单一虚拟继承

发布于 2024-12-03 23:03:30 字数 342 浏览 3 评论 0原文

据我所知,基类的虚拟继承在多个派生类之间创建了一个公共共享基类,从而解决了 DDD 问题。如果我的基类只有一个派生类,那么我虚拟继承基类或非虚拟继承基类时是否有区别?基本上我试图理解查询中提供的解释 是否可以在编译时禁止从类派生? 其中,Usage_lock 基类实际上是继承的,以防止从 Usable 类派生。如果我删除这个虚拟键,行为就会改变,即我能够从 Usable 派生子类。所以我想了解单继承场景中虚拟键造成的差异。

I understand that virtual inheritance of a base class creates a common shared base class among multiple derived classes, thus addressing the DDD problem. If I have only one derived class for my base class, is there a difference when I inherit the base virtually or non-virtually ? Basically I am trying to understand explanation provided in the query Is it possible to forbid deriving from a class at compile time? where Usage_lock base class is inherited virtually to prevent derivations from the class Usable. If I remove this virtual key, the behaviour changes i.e. I am able to derive subclasses from Usable. So I want to understand difference cause by virtual key in single inheritance scenarios.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

绝影如岚 2024-12-10 23:03:30

单个虚拟继承情况的主要区别在于,只有最派生的类调用虚拟继承基的构造函数,并且所有其他类都提供对构造类的引用(这发生在幕后)。

因此,在示例中,由于尝试进一步派生 Usable 需要新类调用 Usable_lock 构造函数(这是私有的),因此任何其他类都不可能源自Usable。只有 Usable 被允许构造锁对象,因为它是锁的友元。

The primary difference in a single virtual inheritance case is that only the most-derived class calls the constructor of virtually inherited bases, and all of the other classes are provided a reference to the constructed class (this happens behind the scenes).

So, in the example, the since attempting to further derive Usable would require the new class to call the Usable_lock constructor (which is private), it is impossible for any other classes to be derived from Usable. Only Usable is allowed to construct the lock object, due to it being a friend of the lock.

你的呼吸 2024-12-10 23:03:30

虚拟继承的引入基本上是为了解决菱形继承的经典问题。

考虑以下类:

class Base {};

class Derived1: Base {};
class Derived2: Base {};

struct MostDerived: Derived1, Derived2 {};

由于这个菱形层次结构,这里的 MostDerived 类有 2 个 Base 实例。

为了解决这个问题,C++ 使用virtual 关键字并引入了虚拟继承的概念。
因此,在此处添加 virtual 关键字,如下所示:

class Derived1: virtual Base {};
class Derived2: virtual Base {};

确保现在 MostDerived 类中只有一个 Base 实例。
MostDerived 类通过调用其构造函数来实例化 Base 类的实例。

有了上述背景(强调粗体文本),请考虑以下内容:代码示例:

Usable类实际上派生自Usable_lock,因此派生类Usable必须实例化Usable_lock 对象的基类,通过调用其构造函数来实现。

但是 Usable_lock 类有一个私有构造函数,因此只有该类本身可以访问该构造函数,从而防止其他类从它派生。


参考 C++03 标准:
第12.6.2节初始化基地和成员
第 6 段:

所有代表虚拟基类的子对象都由最底层派生类(1.8)的构造函数初始化。如果最底层派生类的构造函数没有为虚拟基类 V 指定 mem-initializer,则调用 V 的默认构造函数来初始化虚拟基类子对象。如果 V 没有可访问的默认构造函数,则初始化是错误的。在执行任何非最派生类的类的构造函数期间,应忽略命名虚拟基类的内存初始化程序。

Virtual Inheritance was basically introduced to solve the classical problem of Diamond shaped Inheritance.

Consider, the following classes:

class Base {};

class Derived1: Base {};
class Derived2: Base {};

struct MostDerived: Derived1, Derived2 {};

MostDerived class here has 2 instance of Base because of this diamond shaped hierarchy.

To solve this problem, C++ uses the virtual keyword and introduces the concept called Virtual Inheritance.
Thus adding the virtual keyword here, as:

class Derived1: virtual Base {};
class Derived2: virtual Base {};

Ensures that now there will only be one instance of Base inside MostDerived class.
And the MostDerived class instantiates this instance of Base class by calling its constructor.

With the above background(emphasized bold text), consider the following for the code example:

Usable class derives virtually from Usable_lock, so the derived class Usable MUST instantiate the Usable_lock base class of the object by calling its constructor.

But Usable_lock class has an private constructor so only the class itself can access the constructor, thus preventing other classes from deriving from it.


Reference from the C++03 Standard:
Section 12.6.2 Initializing bases and members
Paragraph 6:

All sub-objects representing virtual base classes are initialized by the constructor of the most derived class(1.8). If the constructor of the most derived class does not specify a mem-initializer for a virtual base class V, then V’s default constructor is called to initialize the virtual base class subobject. If V does not have an accessible default constructor, the initialization is ill-formed. A mem-initializer naming a virtual base class shall be ignored during execution of the constructor of any class that is not the most derived class.

第几種人 2024-12-10 23:03:30

虚拟基类将由最派生的类构造。通过虚拟派生并将此类基类的构造函数设为私有,其他类就无法构造它,从而有效地防止派生。然而,它是一个相当人为的构造,并且也带来了一些开销。

A virtual base class will be constructed by the most derived class. By deriving virtually, and making the constructor of such base private, there is no way another class may construct it, hence effectively preventing derivation. However, its quite an artificial construct, and it comes with some overhead too.

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