In the previous article, the effect of virtual inheritance on C + + on the order of constructor calls to the base class was explained. After careful scrutiny, it was found that the relationship between the virtual inheritance and the ordinary inheritance was not fully understood. So use the following text to explain again.
First, repeat the difference between a virtual inheritance and a normal inheritance:
assuming that derived inherits from the base class, then derived and base are a "is a" relationship, that is, the derived class is the base class, and vice versa;
assuming that derived is inherited from the base class, then DERIVD and base are a "has a" relationship, that is, the derived class has a vptr that points to the base class.
Therefore, virtual inheritance can be considered not as an inheritance relationship, but as a combination of relationships. Because virtual inheritance has "inherited" two keywords, most people think that virtual inheritance is not much different from the usage of normal inheritance. This is used in the inheritance system, this kind of fictitious inheritance is considered to be the harm of ordinary inheritance is better big. Let's use an example to illustrate the problem:
Class Base
{public
:
base () {cout<< "base::base ()!" <<endl;}
void Printbase () {cout<< "Base::p rintbase ()!" <<endl;}
;
Class Derived:public base
{public
:
derived () {cout<< "derived::d erived ()!" <<endl;}
void printderived () {cout<< "derived::p rintderived ()!" <<endl;}
;
The above is the common inheritance implementation, in the actual application, we can use the following code for type conversion:
int main (int argc, const char * argv[])
{
derived oo;
Base Oo1 (static_cast<base> (OO));
Oo1.printbase ();
Derived oo2 = static_cast<derived&> (oo1);
Oo2.printderived ();
return 0;
}
There is no error in compiling, and the correct result is obtained. The results are:
Base::base ()!
Derived::d erived ()!
Base::p rintbase ()!
Derived::p rintderived ()!
Instead, the normal inheritance above becomes virtual inheritance, as the following code:
Class Base1
{public
:
base1 () {cout<< "base::base ()!" <<endl;}
void Printbase () {cout<< "Base::p rintbase ()!" <<endl;}
;
Class Derived1:virtual public base1
{public
:
derived1 () {cout<< "derived::d erived ()!" <<endl;}
void printderived () {cout<< "derived::p rintderived ()!" <<endl;}
;
int main (int argc, const char * argv[])
{
derived1 oo;
Base1 oo1 (static_cast<base1> (OO));
Oo1.printbase ();
Derived1 Oo2 = static_cast<derived1&> (oo1);
Oo2.printderived ();
return 0;
}
Compile the code above, prompting the following:
You can see that the base class cannot be converted to an inheriting class through static_cast. We know that the cast function provided by C + + static_cast is generally feasible for the conversion of class objects in the inheritance system. So why can't it be here? It is also necessary to explain the problem from an internal implementation of virtual inheritance.
The original model of virtual base class is to add a pointer vptr to each associated virtual base class in class object, which points to the virtual base class table. Some compilers import a virtual base class table directly from a virtual table that already exists in the inheriting class. Anyway, because the virtual inheritance has completely destroyed the inheritance system, it is not possible to convert the type according to the normal inheritance system.
In any case, virtual inheritance in type conversion is important to pay attention to. Do not easily use virtual inheritance, let alone on the basis of virtual inheritance of type conversion, remember to remember.