Anda di halaman 1dari 5

Inheritance

C++ supports the concept of reusability, so that data redundancy can be reduced. The classes can be reused in many ways, and the most convenient one is inheritance. The mechanism of creating new classes, reusing the properties of the existing one is called inheritance (or derivation).

Defining derived classes


A derived is defined by specifying its relationship with the base class(es) in addition to its own details. The general form is: class Base Ex. class derived_class_name : visibility_mode base_class_name { { . . //members of derived class }; } class Derived: public Base { .. Visibility mode in nothing but the access specifier keywords (i.e. private, }; protected, public), and it is optional. The default (when not present) visibility mode is private. The visibility mode specifies how the properties of base class are derived (privately, protected, or publicly). And the colon ( : ) indicates that the derived_class is derived from base_class.

Various inheritances
1. Single inheritance Here the derived class inherits only one class, the base one. Base

Derived Here the derived class inherits the two member functions setD() and getD(). We can get different results by changing the visibility mode. a. If the mode is public then the public members of the base class are inherited in the public section of the derived class. b. If the mode is private then the public members of the base class are inherited in the private section of the derived class.
Making private members inheritable

So we can see that the private members of the base class cannot be inherited. But there may arise some situation where we need to inherit the private member also. C++ introduces a third access modifier known as protected.

class Base { int x; public: void setB(int a) {x=a;} int getB() {return x;} }; class Derived:public Base //publicly derived { int y; public: void setD(int a) {y=a;} int getD() {return y;} }; int main() { Derived obj; obj.setB(10); /*base member function is accesed*/ obj.setD(11); cout<<obj.getB(); //displays 10 cout<<obj.getD(); //displays 11 return 0; }

A protected member behaves same like an private member, except that it can be inherited. Now if we inherit a class the derivation will be as follows: Table: Visibility of members Base class visibility Private Protected Public Derived class visibility Public derivation Private derivation Protected derivation Not inherited Not inherited Not inherited Protected Private Protected Public Private Protected

2. Multilevel inheritance Here a class is derived from a class which is derived from another class.

Base

3. Multiple inheritance Here a class is derived from more than one class. Base1 Base2 class Base1 { Derived int x; public: void setx(int a) {x=a;} int getx() {return x;} }; class Base2 { int y; public: void sety(int a) {y=a;} int gety() {return y;} }; class Derived:public Base1, public Base2 { //multiple classes can be inherited //with comma separation int z; public: void set(int a) {z=a;} int get() {return z;} }; int main() { Derived obj; obj.setx(10; obj.sety(11); obj.set(12); cout<<obj.getx(); //displays 10 cout<<obj.gety(); //displays 11 cout<<obj.get(); //displays 12 return 0; }

Derived1 class Base { int x; Derived2 public: void setB(int a) {x=a;} int getB() {return x;} }; class Derived1:public Base { int y; public: void setD(int a) {y=a;} int getD() {return y;} }; class Derived2:public Derived1 { int z; public: void set(int a) {z=a;} int get() {return z;} }; int main() { Derived2 obj; obj.setB(10; obj.setD(11); obj.set(12); cout<<obj.getB(); //displays 10 cout<<obj.getD(); //displays 11 cout<<obj.get(); //displays 12 return 0; }

4. Hierarchical inheritance Here a single class serves as a base class for more than one derived classes. It usually makes a tree structure. class A int main() Base { { Derived public: B b; void fA() C c; {cout<<fA() is called\n;} b.fA(); Derived2 Derived1 }; b.fB(); class B: public A c.fA(); { c.fC(); public: return 0; void fB() } {cout<<fB() is called\n;} }; Output class C: public A { fA() is called public: fB() is called void fC() fA() is called {cout<<fC() is called\n;} fC() is called };

5. Hybrid inheritance As the name indicates, it is simply the mixture of all above kinds of inheritances. class A { public: void fA() {cout<<fA() is called\n;} }; class B: public A { public: void fB() {cout<<fB() is called\n;} }; class C { public: void fC() {cout<<fC() is called\n;} }; class D: public B, public C { public: void fD() {cout<<fD() is called\n;} }; Base2 Base2

Derived1 int main() { D obj; obj.fA(); obj.fB(); obj.fC(); obj.fD(); return 0; } Output fA() is called fB() is called fA() is called fC() is called

Derived2

Derived3

Ambiguity problem in inheritance


Identical members in more than one base classes of derived class (see ex.1). Two or more base class of a derived class, in turn inherit from a common base class. this is known as diamond shaped inheritance (see ex.2).
Base

Ex.1

Ex.2 class A { public: void show(); }; class B: public A {}; class C: public A, public B {}; class D: public B, public C {}; void main() { D obj; Obj.show();
Derived1 Derived2

class A { public: void show(); }; class B { public: void show(); }; class C: public A, public B {}; void main() { C obj; Obj.show(); /*ambiguity, which version of show() is to be called*/ }

Derived3

/*ambiguity, which version of show() is to be called*/ }

Solution:

Using the scope resolution operator and passing the actual owner class to call the members.(see Ex.1)
Ex.2 Ex.1 class A { public: void show(); }; class B { public: void show(); }; class C: public A, public B {}; void main() { C obj; Obj.A::show(); //calls show() from class A Obj.B::show(); //calls show() from class A } class A { public: void show(); }; class B { public: void show(); }; class C: public A, public B { public: void show(); //override both of the //inherited functions }; void main() { C obj; Obj.show(); //calls show() from class C }

By the means of overriding.(see Ex.2)


Overriding: It is the ability to change the definition of an inherited method or attribute in a subclass. Here we define a member function in the derived class in such a manner that its name and signature match those of a base class function. So it results in two functions of same name and signature. Overloading vs Overriding o The type and signature of two or more functions are same in overriding. But the signatures are not same in overriding though the name are same. o The same name functions are present in same class in overloading. In overriding one function is kept in base class and one in derived class. o Overloaded functions can be called directly and distinguished by the type and number of parameter passed. The function of the derived class can be called directly, and the base version is called by using scope resolution operator.

By using virtual base class.(see Ex.3)


This feature is more handy to solve ambiguity in diamondshaped-inheritance. The duplication of members due to multiple inheritance paths can be avoided by making the common base class as virtual base class at the time of declaration of intermediate derived classes. Here the compiler takes necessary care to see that only one copy of that class is inherited, regardless how many inheritance paths exist between the virtual base class and a derived class. NB: The keywords virtual and public may be used in either order.

Ex.3 class A { .. };

class B: public virtual A { .. };


class C: public virtual A { .. }; class D: public B, public C { .. }; //only one copy of A //will be inherited

Constructor and destructor in inheritance


Constructors are invoked in the following order: 1. Virtual base class constructors in the order of inheritance 2. Non-virtual base class constructors in the order of inheritance 3. Member objects constructors in te order of declaration 4. Derived class constructor Destructors are invoked in the reverse order. The following example illustrates this.
#include<iostream> #include<conio.h> using namespace std; class a { public: a() {cout<<"constructor of class a called\n";} ~a() {cout<<"destructor of class a called\n";getch();} }; class b { public: b() {cout<<"constructor of class b called\n";} ~b() {cout<<"destructor of class b called\n";} }; class c : virtual public a { public: c() {cout<<"constructor of class c called\n";} ~c() {cout<<"destructor of class c called\n";} }; class d : virtual public a { public: d() {cout<<"constructor of class d called\n";} ~d() {cout<<"destructor of class d called\n";} }; class e {

public: e() {cout<<"constructor of class e called\n";} ~e() {cout<<"destructor of class e called\n";}


}; class f : public b, public c, public d { private: e x; public: f() {cout<<"constructor of class f called\n";} ~f() {cout<<"destructor of class f called\n";} }; int main() { f obj; getch(); }

Output
constructor of class a called constructor of class b called constructor of class c called constructor of class d called constructor of class e called constructor of class f called destructor of class f called destructor of class e called destructor of class d called destructor of class c called destructor of class b called destructor of class a called

bbb

Anda mungkin juga menyukai