What is the role of virtual inheritance?

Source: Internet
Author: User

Virtual inheritance
 
Classes in the standard I/O library all inherit a common abstract base class Ios. The abstract base class manages the condition state of the stream and saves the buffer zone read and written by the stream. The istream and ostream classes directly inherit this public base class. The library defines another class named isotream, which inherits both istream and ostream. The iostream class can both read and write streams. If the I/O type uses regular inheritance, each iostream object may contain two IOS sub-objects: one included in its istream sub-object and the other included in its ostream sub-object. From the design perspective, this implementation is wrong: the iostream class wants to read and write a single buffer, and it wants to share the condition state across the input and output operators.
 
In C ++, virtual inheritance is used to solve such problems. Virtual inheritance is a mechanism in which a class indicates through virtual inheritance that it wants to share the state of its virtual base class. Under virtual inheritance, for a given virtual base class, no matter how many times the class appears as a virtual base class in the derived hierarchy, only one shared base class sub-object is inherited. The shared base class sub-object is called the virtual base class ).
 
Set the virtual base class by adding the keyword virtual in the list of derived classes, for example:
Class istream: Public Virtual IOS {...};
Class ostream: virtual public IOS {...};
Class iostream: Public istream, public ostream {...};
 
Assume that a member named X is inherited from multiple derived paths. There are three possibilities:
1) if X represents the same virtual base class member in each path, there is no ambiguity, because a single instance that shares the member;
2) If X is a member of the virtual base class in a path and X is a member of the derived class in another path, there is no ambiguity either-the priority of a particular derived class instance is higher than that of a shared virtual base class instance.
3) if each inherited path X represents different members of the derived class, direct access to the member is ambiguous.
 
For example:

# Include <iostream>

Class B {
Public:
Void print (){
STD: cout <"B" <STD: Endl;
}
};

Class D1: Public Virtual B {
};

Class D2: Public Virtual B {
Public:
Void print (){
STD: cout <"D2" <STD: Endl;
}
};

Class DD: Public D1, public D2 {
};

Int main (){
Dd d;
D. Print (); // OK: Call D2: Print

Return 0;
}
 
Special initialization Semantics
 
Generally, each class only initializes its own direct base class. This initialization policy fails when applied to the virtual base class. If regular rules are used, the virtual base class may be initialized multiple times. Class will be initialized along each inheritance path that contains the virtual base class.
 
To solve this problem of repeated initialization, special processing is performed on Initialization from classes inherited by classes with virtual base classes. In virtual derivation, the constructor of the lowest-layer derived class initializes the virtual base class.
 
Although the virtual base class is initialized by the lowest-layer derived class, any class that directly or indirectly inherits the virtual base class must also provide its own initialization type for the base class. As long as you can create an independent object of the virtual base class derived class type, the class must initialize its own virtual base class. These initialization methods are only used when creating intermediate objects.
 
For example, we have four classes: zooanimal, bear, raccoon, and Panda. They construct an inheritance level: Bear and raccoon inherit zooanimal, and Panda inherit bear and raccoon. Then their constructor is like:
Bear: bear (STD: string name, bool onexhibit): zooanimal (name, onexhibit, "bear "){}
Raccoon: Raccoon (STD: string name, bool onexhibit): zooanimal (name, onexhibit, "raccoon "){}
Panda: Panda (STD: string name, bool onexhibit): zooanimal (name, onexhibit, "Panda"), bear (name, onexhibit), raccoon (name, onexhibit) {}
 
When creating a panda object, the construction process is as follows:
1) First, use the initialization type specified in the constructor initialization list to construct the zooanimal part;
2) Next, construct the bear section (before the bear section in the derived list ). Ignore the initialization type used for the zooanimal constructor in the bear initialization list;
3) then, construct the Raccoon part and ignore the zooanimal initialization type again;
4) Finally, construct the panda part.
 
If the panda constructor does not explicitly initialize the zooanimal base class, use the zooanimal default constructor. If zooanimal does not have the default constructor, the Code fails.
 
No matter where the virtual base class appears in the inheritance level, the virtual base class is always constructed before the non-virtual base class is constructed.
 
For example, the following inheritance relationship exists:
Class character {};
Class bookcharater: Public Character {};
Class toyanimal {};
Class teddybear: Public bookcharacter, public bear, Public Virtual toyanimal {};
 
Intuitive inheritance diagram:
Check the direct base class in declared order to determine whether there is a virtual base class. In the above example, first check the inheritance subtree of bookcharacter, then check the inheritance subtree of Bear, and finally check the inheritance subtree of toyanimal. Check each subtree in the order of derived classes from the root class to the lowest layer. Check that zooanimal and toyanimal are virtual base classes in sequence.
 
The Constructing order of the teddybear virtual base class is zooanimal and then toyanimal (Check order ). Once a virtual base class is constructed, a non-virtual base class constructor is called in the declared order: bookcharacter, which calls the character constructor and bear. Here, teddybear, a derived class from the lowest layer, specifies the initialization formula used for zooanimal and toyanimal.
 
Of course, the calling sequence of the Destructor is opposite to that of the constructor.
 
The sample code is as follows:
 

# Include <iostream>

Class character {
Public:
Character (){
STD: cout <"character constructor" <STD: Endl;
}
~ Character (){
STD: cout <"character destructor" <STD: Endl;
}
};

Class bookcharacter: Public Character {
Public:
Bookcharacter (){
STD: cout <"bookcharacter constructor" <STD: Endl;
}
~ Bookcharacter (){
STD: cout <"bookcharacter destructor" <STD: Endl;
}
};

Class zooanimal {
Public:
Zooanimal (){
STD: cout <"zooanimal constructor" <STD: Endl;
}
~ Zooanimal (){
STD: cout <"zooanimal destructor" <STD: Endl;
}
};

Class bear: Public Virtual zooanimal {
Public:
Bear (){
STD: cout <"Bear constructor" <STD: Endl;
}
~ Bear (){
STD: cout <"Bear destructor" <STD: Endl;
}
};

Class toyanimal {
Public:
Toyanimal (){
STD: cout <"toyanimal constructor" <STD: Endl;
}
~ Toyanimal (){
STD: cout <"toyanimal destructor" <STD: Endl;
}
};


Class teddybear: Public bookcharacter, public bear, Public Virtual toyanimal {
Public:
Teddybear (){
STD: cout <"teddybear constructor" <STD: Endl;
}
~ Teddybear (){
STD: cout <"teddybear destructor" <STD: Endl;
}
};

Int main (){
Teddybear TB;

Return 0;
}

The running result is as follows:

Zooanimal Constructor
Toyanimal Constructor
Character Constructor
Bookcharacter Constructor
Bear Constructor
Teddybear Constructor
Teddybear destructor
Bear destructor
Bookcharacter destructor
Character destructor
Toyanimal destructor
Zooanimal destructor


Terminated with return code 0
Press any key to continue...

 

This article from http://bbs.csdn.net/topics/100148304

What is the role of virtual inheritance?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.