C + + Multiple inheritance

Source: Internet
Author: User

1. Three ways to inherit:

Public inheritance, private inheritance (private), protection Inheritance (protected)
A description of the three inheritance methods, as shown in the following table:

Characteristics Public inheritance Protect inheritance Private inheritance
Public members become Public members of derived classes Protected members of derived classes Private members of derived classes
Protect members into Protected members of derived classes Protected members of derived classes Private members of derived classes
Private members become Accessible only through the base class interface Accessible only through the base class interface Accessible only through the base class interface
Can I convert implicitly? Is Is Whether

                                                           ,         &NB Sp                          ,         &NB Sp                          ,         &NB Sp                          ,         &NB Sp                          ,         &NB Sp                          ,         &NB Sp             

2. What is multiple inheritance

When a class has more than one base class, this inheritance is called multiple inheritance.
For example, there are two classes, waiter class waiter, singer Class singer, we have a class is both a waiter and a singer,
Then we can define a multiple-inheritance relationship for the class as follows:

class waiter{}; class singer{}; class Singerwaiter: public Waiter, public singer{};

3. What are the problems with multiple inheritance?
Multiple inheritance is more complex and prone to problems than single inheritance, so we do not recommend using multiple inheritance.
The two main problems with multiple inheritance are:
1) from two different base classes, inherit the same name method
As shown in the following example:

classwaiter{ Public:    voidWork () {std::cout<<"Service"<<Std::endl;}};classsinger{ Public:    voidWork () {std::cout<<"Sing"<<Std::endl;}};classSingerwaiter: PublicWaiter, Publicsinger{};intMain () {Singerwaiter singerwaiter;    Singerwaiter.work (); return 0;}

The compiler does not know which base class's work method to call, so it will report singerwaiter.work ();
2) indirectly inherit multiple instances of the same class from multiple base classes
As shown in the following example:

 class   worker{};  class  Waiter:public   worker{};  class  Singer:public   worker{};  class  Singerwaiter:public  waiter,public  Span style= "color: #000000;" > singer{};  int      main () {Singerwaiter singerwaiter;    Worker  *PW = &singerwaiter;  return  0  ;}  

Will error worker *PW = &singerWaiter; base class worker is not clear.
This is because the constructors for the waiter class and the singer class are called separately when the Singerwaiter object is created.
The waiter class and the singer class also invoke the constructor of the worker class separately, generating two instances of the worker class,
So the PW pointer does not know which worker instance to point to.

4. How to solve the problems caused by multiple inheritance
for problem one, when we call, we need to explicitly indicate which class to invoke , as follows:

int Main () {    singerwaiter singerwaiter;    Singerwaiter.waiter::work (); // Methods to invoke the waiter class    Singerwaiter.singer::work (); // Methods to invoke the singer class    return 0 ;}

for question two, we introduce the concept of virtual base class. is as follows:

 class   worker{};  class  Waiter:virtual   worker{};  class  Singer:virtual   worker{};  class  Singerwaiter:public  waiter,public  Span style= "color: #000000;" > singer{};  int      main () {Singerwaiter singerwaiter;    Worker  *PW = &singerwaiter;  return  0  ;}  

When we declare a virtual keyword when a subclass inherits, it indicates that the base class worker is a virtual base class .
Waiter Objects and singer objects, which are generated when singerwaiter are instantiated, share a base class worker object.

5. Problems to be aware of using virtual base classes
We know that in an inheritance relationship, the constructor of a class has transitivity, as shown in the following code:

classa{Private:    intA; Public: A (intn=0): A (n) {}int Get(){returnA;}};classB: Publica{Private:    intb; Public: B (intm=0,intn=0): A (n), B (m) {}int Get(){returnb;}};classC: Publicb{Private:    intC; Public: C (intq=0,intm=0,intn=0): B (M,n), C (q) {}int Get(){returnC;} voidShow () {std::cout<<a::Get() <<" "<<b::Get() <<" "<<c::Get() <<Std::endl; }};intMain () {C C (1,2,3);    C.show (); return 0;}

The output is: 3 2 1
The constructor for C is called, and the B,a constructor is initialized with the arguments passed in.

Let's look at the case where the virtual base class is used:

classa{Private:    intA; Public: A (intn=0): A (n) {}int Get(){returnA;}};classB:Virtual  Publica{Private:    intb; Public: B (intm=0,intn=0): A (n), B (m) {}int Get(){returnb;}};classC: Publicb{Private:    intC; Public: C (intq=0,intm=0,intn=0): B (M,n), C (q) {}int Get(){returnC;} voidShow () {std::cout<<a::Get() <<" "<<b::Get() <<" "<<c::Get() <<Std::endl; }};intMain () {C C (1,2,3);    C.show (); return 0;}

The output is: 0 2 1
Note A does not initialize with the parameters passed in.
This is because in the virtual base class, we assume that there will be multiple subclasses passing arguments to the virtual base class, in order to avoid this situation,
In the case of virtual base classes, subclass C is forbidden to pass arguments to virtual base class A using intermediate Class B, at which point A's default constructor is called.
So how do we use parameters to initialize the virtual base class?
The answer is that we can initialize the constructor of the virtual base class A directly in subclass C, as shown in the following code:

classa{Private:    intA; Public: A (intn=0): A (n) {}int Get(){returnA;}};classB:Virtual  Publica{Private:    intb; Public: B (intm=0,intn=0): A (n), B (m) {}int Get(){returnb;}};classC: Publicb{Private:    intC; Public: C (intq=0,intm=0,intn=0): A (M), B (M,n), C (q) {}int Get(){returnC;} voidShow () {std::cout<<a::Get() <<" "<<b::Get() <<" "<<c::Get() <<Std::endl; }};intMain () {C C (1,2,3);    C.show (); return 0;}

The output is: 3 2 1

Skip the Intermediate class and call the constructor of the base class directly, which is only suitable for virtual base classes.
"Indirect non-virtual base class not allowed" is an error in non-virtual base class.

Reference: "C + + primer.plus" pp.551-567

C + + Multiple inheritance

Related Article

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.