Multiple inheritance is often considered a complex and unnecessary part of OOP. Multiple inheritance faces crash scenario is not unimaginable, take a look at the following example.
1. Name conflicts
Look at the following scenarios:
If both the Dog class and the Bird class have a method named Eat (), the subclass does not override the method. If the Eat () method of the subclass is called at this point, the compiler will report an error stating that the call to eat () is ambiguous (not knowing whether to invoke the Eat () method inherited from the Dog class or The Eat () method inherited from the Bird class). The code is as follows:
classdog{ Public: Virtual voideat () {};};classbird{ Public: Virtual voideat () {};};classDogbird: PublicDog, Publicbird{};intMain () {Dogbird db; Db.eat (); //bug! Ambiguous call to Method eat () return 0;}/*Compile error: [[email protected] aaa]$ clang++ aa.ccaa.cc:21:8: Error:member ' eat ' found in multiple base classes of different Types Db.eat (); bug! Ambiguous call to Method eat () ^aa.cc:4:18:note:member found by ambiguous name lookup virtual void Eat () {}; ^aa.cc:10:18:note:member found by ambiguous name lookup virtual void Eat () {}; ^1 error generated.*/
Workaround:
#include <iostream>using namespacestd;classdog{ Public: Virtual voidEat () {cout <<"The Dog has eaten."<<Endl;};} ;classbird{ Public: Virtual voidEat () {cout <<"The Bird has eaten."<<Endl;};} ;classDogbird: PublicDog, Publicbird{};intMain () {Dogbird db; Static_cast<Dog> (db). Eat ();//Slices, calling Dog::eat ()Db. Bird::eat ();//Calls bird::eat () return 0;}/*output:the Dog has eaten. The Bird has eaten.*/To disambiguate, either rewrite the Eat () method in the Dogbird class, or display the version of the parent class that indicates which of the call is being called. 2. Ambiguous base class
Look at the following scenarios:
Although name ambiguity may be generated, C + + allows this type of class hierarchy. For example, if the Animal class has a public method sleep (), the Dogbird object will not be able to call this method because the compiler does not know whether to call the version inherited by the Dog or the version inherited by the Bird. The code is as follows:
classanimal{ Public: voidsleep () {}};classDog: Publicanimal{};classBird: Publicanimal{};classDogbird: PublicDog, Publicbird{};intMain () {Dogbird db; Db.sleep (); return 0;}/*compilation error occurred [[email protected] ~]$ clang++ aa.ccaa.cc:25:8: error:non-static member ' sleep ' found in multiple Base-class su Bobjects of type ' Animal ': CLA-Class Dogbird-Class Animal class Dogbird-Class Dog SS Animal Db.sleep (); ^aa.cc:7:10:note:member found by ambiguous name lookup void sleep () {} ^1 error generated.*/
The best way to use the "Diamond" class hierarchy is to set the topmost class as an abstract class, with all methods set to pure virtual methods. Since a class only declares a method without providing a definition, there is no method in the base class that can be called, so there is no ambiguity at this level. The code is as follows:
#include <iostream>using namespacestd;classanimal{ Public: Virtual voidSleep () =0;};classDog: Publicanimal{ Public: Virtual voidsleep () {cout<<"Dog sleep!"<<Endl; }};classBird: Publicanimal{ Public: Virtual voidsleep () {cout<<"Bird sleep!"<<Endl; }};classDogbird: PublicDog, Publicbird{ Public: //Note: Although syntactically speaking, Dogbird can not override the Sleep method//However, when you call the sleep method of the Dogbird class again, it is not clear whether it is the dog class or the bird class. Virtual voidsleep () {cout<<"Dogbird sleep!"<<Endl; }};intMain () {Dogbird db; Db.sleep (); return 0;}/*Output:dogbird sleep!*/Summary
We tend to use multiple inheritance in the context of defining a "as one thing at the same time being another thing," However, the actual objects that follow this pattern are difficult to properly translate into appropriate code, so in engineering we try to avoid using multiple inheritance.
Problems arising from CPP multiple inheritance