Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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
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:
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(); }
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.
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 }
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 };
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
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
16 | 16