2011-09-10 127 views
4

我知道基类的虚拟继承在多个派生类中创建一个公共共享基类,从而解决了DDD问题。如果我的基类只有一个派生类,那么当我虚拟地或非虚拟地继承基类时,是否有区别?基本上我试图理解在查询Is it possible to forbid deriving from a class at compile time?中提供的解释,其中Usage_lock基类实际上被继承以防止来自类Usable的派生。如果我删除这个虚拟键,行为改变,即我可以从Usable派生子类。所以我想通过单个继承场景中的虚拟键来了解差异原因。单个虚拟继承

回答

2

虚拟基类将由最派生的类构造。通过虚拟推导,并使这种基础的构造者变得私人化,另一个类别不可能构建它,因此有效地防止派生。然而,它是一个相当人造的结构,它也带来了一些开销。

5

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

因此,在本例中,因为试图进一步推导Usable将需要新的类来调用Usable_lock构造函数(这是私人的),这是不可能的从Usable得到的任何其他类。只有Usable被允许构造锁对象,因为它是锁的朋友。

+0

谢谢,我可以看到,通过在基础构造函数中设置断点。谢谢。 – irappa

2

虚拟继承基本上被引入来解决经典问题Diamond shaped Inheritance

考虑,以下类:这里

class Base {}; 

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

struct MostDerived: Derived1, Derived2 {}; 

MostDerived类有因为这种菱形层次的Base 2实例。

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

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

确保现在只会有内部MostDerivedBase一个实例。
MostDerived类通过调用它的构造函数来实例化Base类的这个实例。

利用上述背景(强调粗体文本),考虑代码示例以下:

Usable类从Usable_lock几乎导出,所以派生类UsableMUST实例化Usable_lock基类的对象的通过调用它的构造函数。

但是Usable_lock类有一个私有构造函数,所以只有类本身可以访问构造函数,从而防止其他类从它派生。从C++ 03标准


参考:
第12.6.2初始化碱和构件
第6段:

所有子对象表示虚拟基类由最派生类的构造函数初始化(1.8)。如果大多数派生类的构造函数没有为虚拟基类V指定mem-initializer,则调用V的默认构造函数来初始化虚拟基类子对象。如果V没有可访问的默认构造函数,则初始化格式不正确。在执行任何不是派生类最多的类的构造函数时,应忽略命名虚拟基类的mem初始化程序。

+0

任何*真实*的原因downvoting这? –