1. virtual base class
Consider this situation: When part or all of a class is directly derived from another common base class, the members of these directly inherited base classes must have the same name, which leads to ambiguity.
Solution: When the derived class and the direct base class have a problem of ambiguity --> scope of the added class.
When the derived class and indirect base class have a problem of ambiguity --> virtual base class.
2. Description of the virtual base class:
Class derived class name: virtual access permission base class name
{Definition of a derived class };
Note: when defining a derived class, declare the base class to be inherited. The description of the virtual base class is completed in the definition of the derived class.
Purpose: After the base class is described as a virtual base class, no base class copy is generated no matter how many derived classes are generated by the virtual base class-multiple Derived classes share one base class.
Note: If a base class derives from multiple Derived classes, the base class must be declared as a virtual base class in the definition of each derived class. No base class is declared, then the system generates a copy of the base class for the derived class.
Example 1
Class One
{Int B ;};
Class Baseone: virtual public One
{Int b1 ;};
Class Basetwo: virtual public One
{Int b2 ;};
Class Basethree: public Baseone, public Basetwo
{};
3. initialize the virtual base class
(1) The Calling sequence of the derived class constructor: base class constructor --> sub-object constructor --> derived class constructor.
(2) The construction of the virtual base class is completed before the construction of the non-virtual base class. If there are two virtual base classes on the same layer, the construction is called in the instruction order. (3) the virtual base class is constructed only once.
(4) If the virtual base class is a non-virtual base class derived class, the non-virtual base class is called first.
(5) The structure sequence is strictly opposite to that of the structure.
Example 2
# Include
Class Base1
{
Public:
Base1 ()
{
Cout <"Base1 construction." < }
};
Class Base2
{
Public:
Base2 ()
{
Cout <"Base2 construction." < }
};
Class Level1: public Base2, virtual public Base1
{
Public:
Level1 () {cout <"Level1 construction." < };
Class Level2: public Base2, virtual public Base1
{
Public:
Level2 () {cout <"Levle2 construction." < };
Class Toplevel: public Level1, virtual public Level2
{
Public:
Toplevel () {cout <"Toplevel construction." < };
Int main ()
{
Toplevel obj;
}
Program output:
Base1 construction.
Base2 construction.
Levle2 construction.
Base2 construction.
Level1 construction.
Toplevel construction.
Analysis: obj is a Toplevel object. Toplevel has a virtual base class and a non-virtual base class. According to the rules, the virtual base class (Level2) is constructed first. Level2 has a virtual base class and a non-virtual base class. It also constructs a virtual base class, that is, Base1. After Base1 is constructed, it constructs the non-virtual base class Base2 of Level2, finally, Level2 is constructed. At this point, the Toplevel virtual base class is constructed. The following constructs the TopLevel non-virtual base class Level1. First, the constructor virtual base class Base1, which is no longer constructed because Base1 has been constructed, below is Base2, and finally Level1. The last step is
The Toplevel is constructed.
Example 3
# Include
Class
{
Public:
A (char I) {cout <"A construction" < ~ A () {cout <"A destruction." < };
Class B: virtual public
{
Public:
B (char I, char j): A (I) // because the virtual base class A is constructed by A parameter, the construction of A must be called in the derived class B.
{
Cout <"B construction" < }
~ B () {cout <"B destruction." < Private:
Char B;
};
Class C: virtual public
{
Public:
C (char I, char j): A (I) // although the C class of the derived class does not call the constructor of the virtual base class A, because in the derived class B
// Called, but the C constructor must declare A parameter call for the virtual base class.
{
Cout <"C construction" < }
};
Class D: public B, public C
{
Public:
D (char I, char j, char k, char l, char m, char n ):
C (k, l), B (I, j), A (n), aa (m)
{
Cout <"D construction." < }
Private:
A aa;
};
Int main ()
{
D obj ('A', 'B', 'C', 'D', 'E', 'F ');
}
Program output:
A construction f
B construction B
C construction d
A construction e
D construction.
A destruction.
B destruction.
A destruction.
Note: In the constructor of D, A (I) is required. The construction of A uses f.
Analysis: adding A (I) in the D structure is required, because the structure of A is prior to the construction of B and C, that is to say, the parameters passed to B and C cannot be used to construct A. Therefore, the construction of A's parameters must come from D, and the value of D passed to A is obtained.
4. Call Sequence
(1) All the virtual base class constructors are constructed in the order they are inherited.
(2) All constructors of non-virtual base classes are constructed in the order they are inherited.
(3) All Sub-objects are constructed in the declared order.
(4) Structure of the derived class:
A. In an initialization list, the call of the virtual base class and non-virtual base class member functions is displayed at the same time. The virtual base class takes precedence over the non-virtual base class.
B. The virtual base classes at the same layer are called and constructed in the instruction order, and non-virtual base classes are called and constructed in the inheritance order.
C. All the virtual base classes are constructed only once in inheritance, and each sub-object of the virtual base class must be called once.
5. Assignment compatibility rules for virtual base classes
(1) the address of the derived class can be assigned to the virtual base class pointer.
(2) A virtual base class reference can reference a derived class object. (All are big and can be assigned to small ones)