C + + Multiple inheritance

Source: Internet
Author: User

Most applications use common inheritance for a single base class, but in some cases it is necessary to derive a class from more than one direct base class, known as multiple inheritance, which inherits the properties of all its parent classes.

1: Examples of multiple inheritance:

Class Bear:public Zooanimal {};class panda:public Bear, public Endangered {};

Derived classes specify an access level of--public, protected, or private for each base class (either explicitly or implicitly).

2: Under multiple inheritance, the object of the derived class contains the base class sub-object of each base class. When constructing a Panda object, the object contains a Bear class child object (the Bear class child object itself contains a Zooanimal base class sub-object), a endangered class child object, and a non-static data member declared in the Panda class (if any). Such as:

3: Objects that construct derived classes include the construction and initialization of all base class child objects. The constructors of a derived class can pass values to 0 or more base classes in constructor initialization:

Explicitly initialize both base Classespanda::P Anda (std::string name, bool onexhibit): Bear (Name, Onexhibit, "Panda"), Endangered (endangered::critical) {}//implicitly use Bear default constructor to initialize the bear Subobjectpanda::P and A (): Endangered (endangered::critical) {}

  

Constructor initializers can only control the values used to initialize the base class, and cannot control the construction order of the base class. The base class constructor is called in the order in which the base class appears in the class-derived list. For Panda, the order in which the base class is initialized is:

A. Zooanimal, the ultimate base class for the direct base-type bear along the hierarchy from Panda.

B. Bear, the first direct base class.

C. Endangered, the second direct base class, does not have a base class on its own.

D. Panda, initializes the member of the Panda itself, and then runs its constructor function body.

Destructors are always called in reverse order as the constructor runs. In our example, the order in which destructors are called is ~panda, ~endangered, ~bear, ~zooanimal.

4: In multiple inheritance cases, the likelihood of encountering a ambiguity conversion is greater. For example, if you have an overloaded version of the print function:

void print (const bear&); void print (const endangered&); Panda Ying_yang ("Ying_yang");p rint (Ying_yang); Error:ambiguous

Causes a compile-time error to indicate that the call is two semantic.

5: Assuming that all base classes properly define their destructors as virtual functions, the processing of the virtual destructor is consistent regardless of which pointer type the object is deleted from:

Each pointer points to a pandadelete pz; PZ is a zooanimal*delete PB; PB is a bear*delete pp; PP is a panda*delete pe; PE is a endangered*

Assuming that each of these pointers is to a Panda object, the exact same sequence of destructor calls occurs in each case. The order of the destructor calls is reversed in order of the constructor: the Panda destructor is called by the virtual mechanism. With the execution of the Panda destructor, the destructors for endangered, bear, and Zooanimal are called in turn.

As with single inheritance, if a class with more than one base class defines its own destructor, the destructor is only responsible for clearing the derived class. If a derived class defines its own copy constructor or assignment operator, the class is responsible for copying (assigning) all of the base class sub-parts. Only derived classes use the composite version of the copy constructor or assignment operator to automatically copy or assign the base class part.

6: Under multiple inheritance, the name lookup simultaneously counsels all the base classes to inherit the subtree-in our case, find the endangered subtree and the Bear/zooanimal subtree in parallel. If the name is found in more than one subtree, the use of that name must explicitly specify which base class to use, otherwise the use of the name is two semantic.

Assume that both the bear class and the endangered class define a member named Print, Ying_yang.print (cout) If the Panda class does not have the member defined, and such a statement results in a compile-time error.

Derivation only leads to a potential two semantics, which can be avoided if no Panda object calls print. If each print call explicitly indicates which version--bear you want::p rint or endangered::p rint, you can also avoid errors. An error occurs only when there is a ambiguity attempt to use the member.

Even if two inherited functions have different formal parameter lists, an error is generated. Similarly, even if a function is private in one class and is public or protected in another class, it is also an error.

You can resolve ambiguity by specifying which class to use: Ying_yang. Endangered::p rint (cout);

7: Under multiple inheritance, a base class can appear multiple times in a derived hierarchy. such as the IO Library class:

A multiple-inheriting class inherits State and action from each of its parent classes, and if the IO type uses regular inheritance, each Iostream object may contain two iOS child objects: one contained in its IStream sub-object, and the other contained in its Ostream sub-object, from a design standpoint, This implementation is a mistake.

Use virtual inheritance to solve this kind of problem. Virtual inheritance is a mechanism by which a class indicates that it wants to share the state of its virtual base class through virtual inheritance. 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 child object is inherited.

The IStream and Ostream classes perform virtual inheritance of their base classes. By making the base class A virtual base class, IStream and Ostream specify that if other classes (such as iostream) inherit two of them at the same time, only one copy of their public base class appears in the derived class. Set the virtual base class by including the keywords in the derived list:

Class Istream:public virtual iOS {...}; Class Ostream:virtual public iOS {...}; Class Iostream:public IStream, public ostream {...};

8: Consider the following example:

Class Panda:public bear, public raccoon, public Endangered {};

Virtual derivation must be made before any actual need for a virtual derivation is made (in the example, the virtual derivation of the bear class and the Raccoon Class). Virtual inheritance is only necessary when using Panda declarations.

The base class is specified as derived by virtual inheritance by modifying the declaration with the keyword virtual. For example, the following declaration makes the Zooanimal Class A virtual base class for the bear class and the Raccoon class:

The order of the keywords public and virtual are not significantclass raccoon:public virtual Zooanimal {/* ... */};c Lass Bear:virtual public Zooanimal {/* ... */};

9: Assuming that a member named X is inherited through multiple derived paths, there are three possibilities:

A. If X represents the same virtual base class member in each path, there is no ambiguity because a single instance of the member is shared.

B. If x is a member of a virtual base class in a path, and X is a member of a descendant-derived class in another path, there is no ambiguity-the instance of a particular derived class has precedence over the shared virtual base class instance.

C. If each inheritance path X represents a different member of a descendant-derived class, the direct access for that member is two semantic.

10: Each class initializes its own direct base class only. This initialization policy fails when applied to the virtual base class. If you use regular rules, virtual base classes may be initialized more than once. Class is initialized along each inherited path that contains the virtual base class. In the Zooanimal example, using a regular rule will cause both the Bear class and the raccoon class to attempt to initialize the Zooanimal class portion of the Panda object.

In order to solve this repetitive initialization problem, classes inheriting from classes with virtual base classes have special handling of initialization. In a virtual derivation, the virtual base class is initialized by the constructor of the lowest-layer derived class. In our example, when creating a Panda object, only the Panda constructor controls how the Zooanimal base class is initialized.

Although the virtual base class is initialized by the lowest-layer derived class, any class that inherits the virtual base class directly or indirectly must also provide its own initialization for that base class. Whenever you can create a standalone object of a virtual base class derived class type, the class must initialize its own virtual base class, which is used only when creating an object of an intermediate type.

In our hierarchy, you can have an object of type bear, raccoon, or Panda. When you create a Panda object, it is the lowest-layer derived type and controls the initialization of the shared Zooanimal base class: When you create a Bear object (or Raccoon object), the lower-level derived type is not involved. In this case, the bear (or raccoon) constructors directly initialize their Zooanimal base class as usual:

Bear::bear (std::string name, bool onexhibit): Zooanimal (name, Onexhibit, "Bear") {}raccoon::raccoon (std::string name, BOOL onexhibit): Zooanimal (name, onexhibit, "raccoon") {}

Although Zooanimal is not a direct base class for Panda, the Panda constructor also initializes the Zooanimal base class:

Panda::P anda (std::string name, bool onexhibit):     zooanimal (name, Onexhibit, "Panda"), Bear    (name, Onexhibit),    Raccoon (name, onexhibit),    Endangered (endangered::critical),    Sleeping_flag (false) {}bear Winnie ("Pooh");//Bear constructor initializes Zooanimalraccoon Meeko ("Meeko"); Raccoon constructor initializes Zooanimalpanda Yolo ("YOLO"); Panda constructor initializes zooanimal

When you create a Panda object,

First, the constructor initializes the zooanimal part of the initialization specified in the list, and then constructs the Bear section. The initialization of the Zooanimal constructor initialization list is ignored for the bear, and then the raccoon part is constructed, the Zooanimal initialization is ignored again, and finally, the Panda section is constructed.

11: The virtual base class is always constructed before constructing a non-virtual base class, regardless of where the virtual base class appears anywhere in the inheritance hierarchy.

In the derivation of teddybear below, there are two virtual base classes: The Toyanimal base class and the indirect base class zooanimal of the derived bear:

Class Character {/* ... */};class bookcharacter:public Character {/* ... */};class toyanimal {/* ... */};class Ted Dybear:public Bookcharacter, public bear, public virtual toyanimal{/* ... */};

The construction order of the virtual base class of Teddybear is Zooanimal and Toyanimal first. Once a virtual base class is constructed, a constructor for a non-virtual base class is called in the Order of declaration: first, Bookcharacter, which causes the call to the Character constructor and then the bear. Therefore, in order to create the Teddybear object, the constructor is called in the following order:

Zooanimal (); Bear ' s virtual base classtoyanimal (); Immediate virtual base classcharacter (); Bookcharacter ' s nonvirtual base classbookcharacter (); Immediate nonvirtual base classbear (); Immediate nonvirtual base classteddybear (); Most derived class

Here, the lowest-layer derived class teddybear specifies the initialization for Zooanimal and Toyanimal.

The same construction order is used in the composition copy constructor, and the base class is assigned in this order in the composition assignment operator. The order of the call base class destructor is guaranteed to be the reverse of the call order of the constructor.

C + + Multiple 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.