开发者

single virtual inheritance

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 der开发者_运维百科ive subclasses from Usable. So I want to understand difference cause by virtual key in single inheritance scenarios.


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜