Multiple Inheritance in C++
In C++ a class can inherit from more than one class.
Other languages which support multiple inheritance are python, perl, common lisp etc.
In Java, C# and Ruby, it is not possible to have 2 or more base classes for a given class. But C++ allows it.
In Java, C# and Ruby, it is not possible to have 2 or more base classes for a given class. But C++ allows it.
Syntax for
multiple
inheritance is
class cls-name:public base-cls1,public base-cls2,public base-cls3
{
/*code*/
}
The base
class list is comma
separated and must have access specifier for each base class. Each of these
base classes must have been declared earlier.
Derived
class objects
contains sub-objects of each of the base classes.
class LAnimal { public: void walk() { cout<<"walks"; } }; class WAnimal { public: void swim() { cout<<"swims"; } }; class Amphibian:public LAnimal,public WAnimal { }; int main() { Amphibian frog; frog.walk(); frog.swim(); }
In the
above example, class
Amphibian inherits from 2 classes - LAnimal and WAnimal. It has members
of both these base classes. It can call both walk() and swim()
functions.
Constructors
The derived class constructor and
destructors in multiple inheritace will call all of the base
class constructors and destructors.
The order of constructor invocations is same as declaration order of
base classes.
Amphibian constructor will call LAnimal constructor
first, then WAnimal constructor and finally Amphibian constructor. And
order of destructor invocation is reverse of order of constructor
invocation.
Dreaded diamond problem and Virtual Inheritance
When there
is a multilevel and multiple inheritance
together, derived
class may contain more than one instance of an ancestor class. Accessing a member from this base class throws an ambiguity error.
class A { int m; public: void setm(int a){m = a;}; int getm(){return m;} void print(){cout<<"m"<<m<<endl;} }; class B: public A { public: B(){setm(10);}; }; class C:public A { public: C() {setm(20);}; }; class D:public B,public C { /*multiple inherited class*/ }; int main() { D obj; cout<<obj.getm();/*error*/ obj.print();/*error*/ }
When we
compile this program obj.print()throws
ambiguity error.
obj has
members of A class duplicated. It has 2 ms, one is set 10 in B class
constructor. And the other is set to 20 in C class constructor. So
obj.getm() causes a conflict, whether to use m from B class path or m
from C class path.
Similarly
when calling print(), compiler is unable to decide whether to call
print through C class or print through B class.
This is
called dreaded diamond problem because of the shape of inheritance
diagram.
To avoid
this error, virtual
inheritance is used.
Virtual Inheritance
In virtual
inheritance, in spite of multiple paths
to a base class, base class object is included only once.
class A { int m; public: int getm(){return m;} void setm(int a){m = a;} void print(){cout<<"A print";} }; class B:virtual public A { /***code**/ }; class C:public virtual A { /***code**/ }; class D:public B,public C { /**this has only one sub object of A*/ }; int main() { /*code*/ D obj; obj.print();/*No error*/ }
Both B and
C class use virtual inheritance. So when D inherits from both B and C,
it is inheriting only one sub-object of A class. So
there is only one data member called m in D class and only one print function. There will not be any ambiguity when obj.print() function is
called.
Also
observe that obj causes A class constructor to be called
only once and A destructor to be called only once.
And do you know what? This topic and other topics are explained nicely in my C++ app. May be you want to download it from google play.
And do you know what? This topic and other topics are explained nicely in my C++ app. May be you want to download it from google play.
Comments
Post a Comment