You are on page 1of 16

C++ Inheritance

Pi19404
November 25, 2013

Contents

Contents
C++ Inheritance
0.1 Introduction . . . . . . . . . . . . . . . . . . . . 0.2 Inheritance . . . . . . . . . . . . . . . . . . . . . 0.2.1 Multiple Inheritance . . . . . . . . . . 0.2.2 Virtual Base Class . . . . . . . . . . . 0.2.3 Ambiguous base classes . . . . . . 0.2.4 Using Keyword Declaration . . . 0.2.5 Pointer Derived Class and Base 0.2.6 Inherited member access . . . . . . 0.2.7 Increasing Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 3 4 8 9 9 12 14 14

2 | 16

C++ Inheritance

C++ Inheritance
0.1 Introduction
This article describes basic concepts of C++ Inheritance mechanism.

0.2 Inheritance
 Inheritance is a mechanism of reusing and extending existing classes without modifying them, thus producing hierarchical relationships between them.  Inheritance is implemented in C++ through the mechanism of derivation. Derivation allows you to derive a class, called a derived class, from another class, called a base classes  The class whose members you want to include in your new class is called a base class. Your new class is derived from the base class.  You can also add new data members and member functions to the derived class.  When you derive a class, the derived class inherits class members of the base class. You can refer to inherited members (base class members) as if they were members of the derived classes

class A{ //A is the base class }; class B: public A { int a; //we can add new data members void f(); //we can add new member function }; //B is the derived class
 You can modify the implementation of existing member functions or data by overriding base class member functions or data in the newly derived class. If a member of a derived class has the same name as a base class, the base class name is hidden in the derived class.

3 | 16

C++ Inheritance

class A{ public: int a; int func(){cout << "11" << endl;}; }; class B:public A{ public: char a; //overriding data member in class A int func(){cout << "22" << endl;}; }; int main() { B b; A a; cerr << a.func() << endl; //prints 11 cerr << b.func() << endl; //prints 22 overrings func in class A }
 You may derive classes from other derived classes, thereby creating another level of inheritance. The number of levels of inheritance is only limited by resources.

class A {}; class B:public A{}; class C:public B{}; //multiple levels of inheritance
 The new class contains a subobject of the type of the base classes

0.2.1 Multiple Inheritance


 Multiple inheritance allows you to create a derived class that inherits properties from more than one base classes

class A{ public: int a; A():a(10){}; } class B{ public:

4 | 16

C++ Inheritance

int b; B():b(10){}; } class C:public A,public B { //Class C inherits members of class A and B } int main() { C c1; cerr << c1.a << ":"<< c1.b << endl; //Accessing members of base class A and B }
 Because a derived class inherits members from all its base classes, ambiguities can result

class A{ public: int a; //ambiguous member A():a(10){}; }; class B{ public: int a; //ambiguous members B():a(20){}; }; class C:public A,public B { //Class C inherits members of A and B }; int main() { C c1; cerr << c1.a << ":"< endl; //Accessing ambiguous data member }

5 | 16

C++ Inheritance
 In case of ambigious data members a solution would be to override the base class members

class A{ public: int a; //ambiguous member A():a(10){}; }; class B{ public: int a; //ambiguous members B():a(20){}; }; class C:public A,public B { public: int a; //overriding ambigous data members };
 we can still access the override members of the base class using scope resolution operator

class Base{ public: int a; Base():a(10){}; }; class Derived:public Base { public: int a; //overriding ambigous data members Derived():a(100){}; }; int main() { Derived c1; cerr << c1.a << ":"<< endl; //accessing derived class member cerr << c1.Base::a << ":"<< endl; //accessing the base class member }
 A direct base class cannot appear in the base list of a derived class more than once:

class Base{ public:

6 | 16

C++ Inheritance

int a; void disp(){cout << a << endl;} }; class Derived:public Base,public Base //this will give error { public: };

 A derived class can inherit an indirect base class more than once.However this may result in ambiguities since it can be considered that 2 subobjects of Parent class exist which are both accessible throught the derived class.

class Parent{ public: int a; } class Base:public Parent{ public: void disp(){cout << a << endl;} }; //both base and base1 have the same base class class Base1:public Parent{ public: void disp(){cout << a << endl;} }; class Derived:private Base,private Base1 //this will cause error { public: }; int main() { Derived d;

7 | 16

C++ Inheritance

d.disp(); }

0.2.2 Virtual Base Class


 A derived can have virtual and non virtual base classes  If a derived classes ,inherits from same base class via multiple inheritance,it will have 2 subobjects of the base class leading to ambiguity,hence the virtual base class keyword can be used to specify that derived object contain only one copy of the inherited base class.

using namespace std; class Parent{ public: int a; } //virtual base class class Base:public virtual Parent{ public: void disp(){cout << a << endl;} }; //virtual base class class Base1:public virtual Parent{ public: void disp(){cout << a << endl;} }; //not an error due to one subobject of indirect base class class Derived:private Base,private Base1 { public: };
 In an inheritance containing virtual base classes, a name of class member that can be reached through more than one path of inheritance is accessed through the path that gives the most access.

class Parent{ public: int a;

8 | 16

C++ Inheritance

} class Base:public virtual Parent{ public: void disp(){cout << a << endl;} }; class Base1:private virtual Parent{ public: void disp(){cout << a << endl;} }; //Base provides more access class Derived:private Base,private Base1 { public: }; int main() { Derived d; //It choose base,else this line woul //give error due to private inheritance cout << d.a <<endl; //take from Base }

0.2.3 Ambiguous base classes


 The order of derivation is relevant only to determine the order of default initialization by constructors and cleanup by destructors.

0.2.4 Using Keyword Declaration


 A member function in the derived class will hide all other members with same name in the base class regardless of type of arguments or return type

class Base{ private: int a; public: void disp(){cout << a << endl;}//member disp will be hidden

9 | 16

C++ Inheritance

Base():a(10){}; }; class Derived:protected Base { public: void disp(int a){};//member named disp in derived class }; int main() { Derived d; d.disp(); //this will give error since disp function is hidden }

 A using declaration in a definition of a class A allows you to introduce a name of a data member or member function from a base class of A into the scope of A

class Base{ private: int a; public: void disp(){cout << a << endl;} Base():a(10){}; }; class Derived:protected Base { public: //introducing disp function from base to derived class using Base::disp; void disp(int a){}; }; int main() { Derived d; d.disp();//because of using declaration this is allowed //name disp is overloaded with 2 functions }

10 | 16

C++ Inheritance
 If the function with same names as that of base class declared with using keyword is present in the derived class the function in base class will be hidden and no conflict arises.

class Base{ private: int a; public: void disp(){cout << a << endl;} //function in case class Base():a(10){}; }; class Derived:protected Base { public: using Base::disp; //using keyword //function with same name,return type and args in derived class void disp(){cerr << "DErived" << endl;}; void disp(int a){}; }; int main() { Derived d; d.disp();//will print derived ,no conflicts }
 Using Declaration cannot resolve ambiguities due to same inherited members

class Parent{ public: int a; }; class Base:public Parent{ //resolves ambiguities between derived and base class using Parent::a; public: void disp(){cout << a << endl;} }; class Base1:public Parent{}; //multiple inherited class class Derived:public Base,public Base1{

11 | 16

C++ Inheritance

public: using Parent::a; void disp(){cout << a << endl;}; //error,using does not solve ambiguity after resolution //a is accessed vi Base and Base1 } int main() { Base d; d.disp(); }
 The declaration of a member with an ambiguous name in a derived class is not an error. The ambiguity is only flagged as an error if you use the ambiguous member name.

class Parent{ public: int a; }; class Base:public Parent{ using Parent::a; public: void disp(){cout << a << endl;} }; class Base1:public Parent{}; class Derived:public Base,public Base1{ public: using Parent::a; void disp(){}; //a is not used hence no error in compilation };

0.2.5 Pointer Derived Class and Base Class


 Pointer to a Derived class can be converted to pointer of the base class

class Base{ public:

12 | 16

C++ Inheritance

int a; Base():a(10){}; }; class Derived:public Base { public: int a; //overriding ambigous data members Derived():a(100){}; }; int main() { Derived d1; Derived *d2=&d1; // Base *b1; b1=d2; //convers pointer to base class from derived class cerr << b1->a << endl;//prints 10 of base class cerr << d2->a << endl;//prints 100 of derived class }
 A pointer to base class cannot be derived to case class.

In the above example,chaning the main function int main() { Derived d1; Derived *d2=&d1; // Base *b1; d2=b1; //this line will give an error }
 Members and friends of a class can implicitly convert a pointer to an object of that class to a pointer to either protected or public direct or indirect base class and direct private base class.  A direct base class is a base class that appears directly as a base specifier in the declaration of its derived class. An indirect base class is a base class that does not appear directly in the declaration of the derived class but is available to the derived class through one of its base classes For a given class, all base classes that are not direct base classes are indirect base classes. The following example demonstrates direct and indirect base classes  Classes that are declared but not defined are not allowed in base lists.

13 | 16

C++ Inheritance

0.2.6 Inherited member access


 while inheriting the members from base class,we can hide some information of the base class.This can be done by specifying the access specifier.  An access specifier can be public, private, or protected.  In a public base class access the public and protected members of the base class remain public and protected members of the derived class respectively.  In a protected base class access the public and protected members of the base class are protected members of the derived class.  In a private base class access the public and protected members of the base class become the private members of the derived class.  The private members of the base class remain private members of derived classes  Private members of the base class cannot be used by the derived class unless friend declarations within the base class explicitly grant access to them.  The default access specifier is private

0.2.7 Increasing Access


 Suppose class B is a direct base class of class A. To restrict access of class B to the members of class A, derive B from A using either the access specifiers protected or private.  To increase the access of a member x of class A inherited from class B, use a using declaration.You cannot restrict the access to x with a using declarations  Access can be increase to member inherited as private or declared/inherited as protected

class Base{ private: int a; public: void disp(){cout << a << endl;}

14 | 16

C++ Inheritance

Base():a(10){}; }; class Derived:private Base { public: //disp is inherited as private but access increase by using declaration //in public access scope using Base::disp; }; int main() { Derived d; d.disp();//without using declaration will give error }
 Access to members declared as private in the base class cannot be increased

class Base{ private: int a; public: void disp(){cout << a << endl;} Base():a(10){}; }; class Derived:public Base { public: using Base::a; //this line will give error };
 Access to a member cannot be reduced with a using declaration

class Base{ private: int a; public: void disp(){cout << a << endl;} Base():a(10){}; }; class Derived:public Base

15 | 16

C++ Inheritance

{ private: //this will give an error using Base::disp; };

16 | 16