Pergunta

Consider the following sample codes which shows multilevel inheritance:

Case1 : Here the class derived1 is derived from the class base through virtual inheritance and the class derived2 is derived from the class derived1 directly.

class base
{

};

class derived1 : virtual public base
{

};

class derived2 : public derived1
{

};

Case2 : Same as Case1 except that no virtual inheritance is involved

class base
{

};

class derived1 : public base // no virtual inheritance
{

};

class derived2 : public derived1
{

};

Suppose i create an object of the class derived2 in both cases.

  1. How does Case1 and Case2 differ with respect to the containment of sub-objects with in the object of derived2?

  2. Does Case1 have significance over Case2 ?

PS: I am clear with the importance of a virtual base class during multiple inheritance.

Foi útil?

Solução

Without multiple instances of a base class in an inheritance hierarchy there are (at least) two other issue to consider with virtual base classes.

First, a virtual base class is always initialized by the most derived class under construction and before non-virtual base classes. This is most obvious when intermediate classes pass parameters to the virtual base class constructor in their member initialization lists. These initializers will be ignored. It can also make a difference to the order of construction of base classes.

Second, it is not possible to perform a static_cast from a virtual base class to a class that inherits from it.

Outras dicas

There is additional information stored when using virtual inheritance. This is to allow dynamic casts to properly resolve to derived classes in the case of a diamond situation. Your code does not have a diamond situation, so the information is not used.

The additional information can be made visible if you add a data member to the base class:

class base {
protected:
    int i;
};

If you now print the size of each of the derived classes in each of your two cases, you will observe a difference in their sizes from one case to the other.

Edit: Charles Bailey makes excellent points about semantic differences with using virtual inheritance. His first point is particularly interesting, and should be given more consideration. His point is basically that derived2 has an implicit diamond topology. That is, assuming derived1 virtually inherits from base:

class base {};
class derived1 : virtual public base {};

Then, there is no difference between these three versions of derived2, they all behave like the first one:

class derived2 : virtual public base, public derived1 {};
class derived2 : public derived1, virtual public base {};
class derived2 : public derived1 {}

This implies that there is an implicit diamond created when you derive from a class like derived1 (that is, one that has used virtual inheritance).

    base
     |  \
     |   \.(virtual)
     |   / \
     |  /___\
     |    |
     | derived1
     |   /
     |  /
     |./
     / \ 
    /___\
      |
   derived2 

To further illustrate the point, this is allowed when derived1 uses virtual inheritance:

class derived2 : public derived1 {
public:
    derived2 () : base() {}
};

But, it is not allowed if derived1 does not use virtual inheritance.

Virtual inheritence has no significance in your case.
It is only indented for diamon inheritence like:

B: A
C: A
D: B, C

In this case inheritence from A in both cases should be virtual.

Virtual inheritance becomes significant only when the class is included as a base class more than once. In fact the specifier virtual means here "include only once".

When you do not have multiple inheritance you cannot specify the same class several times (circular inheritance is a clear syntax error). Then it comes to how good smart is the optimization in your compiler. If the compiler is perfect, then there is no difference. Practically speaking you pick up the risk that compiler will add something that has relation to multiple inheritance to your class. The less often some feature of the language is used, the bigger the risk that compiler will get confused. Compiler is typically a high quality program, but still this is only a program.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top