0% found this document useful (0 votes)
10 views53 pages

Inheritance

The document provides an overview of inheritance in object-oriented programming, detailing the concepts of base and derived classes, member visibility, and the implementation of constructors and destructors. It also discusses multiple inheritance, function overriding, and the differences between compile-time and run-time polymorphism. Examples in C++ illustrate these concepts, emphasizing the importance of inheritance for code reusability and organization.

Uploaded by

WORLD GAMING UTD
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views53 pages

Inheritance

The document provides an overview of inheritance in object-oriented programming, detailing the concepts of base and derived classes, member visibility, and the implementation of constructors and destructors. It also discusses multiple inheritance, function overriding, and the differences between compile-time and run-time polymorphism. Examples in C++ illustrate these concepts, emphasizing the importance of inheritance for code reusability and organization.

Uploaded by

WORLD GAMING UTD
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 53

CSE 109:INHERITANCE

Credit: Dr. Tanzima Hashem


Professor
CSE, BUET
INHERITANCE
 Inheritance allows one object to inherit member variables and/or
member functions from another object

 Inherited object is called base object


 Inheriting object is called derived object

 Helps programmer to write reusable code


 Helps programmer to write compact code

2
INHERITANCE
 Inheritance starts with defining the base class first
class base-class-name {
…….
};
 Derived class is then defined using the base class
 The general form of deriving a class from another class is as follows:
class derived-class-name: access base-class-name {
………
};
 Access can be either private or public or protected
 Default access is private for derived class, public for derived 3
structure
VISIBILITY OF BASE CLASS MEMBERS IN DERIVED CLASS

Member visibility in derived class

Member access Type of Inheritance


specifier in base
Private Protected Public
class
Private

Protected

Public

4
VISIBILITY OF BASE CLASS MEMBERS IN DERIVED CLASS

Member visibility in derived class

Member access Type of Inheritance


specifier in base
Private Protected Public
class
Private Not Inherited Not Inherited Not Inherited

Protected Private Protected Protected

Public Private Protected Public

5
INHERITANCE: BASE CLASS
#include <iostream>
using namespace std;
class Rectangle {
int width, length;
public:
void set_width(int w) {width=w;}
void set_length(int l) {length=l;}
int area() {return (width*length);}
};

6
INHERITANCE: DERIVED CLASS
class Box: public Rectangle {
int height;
public:
void set_height (int h){height=h;}
int volume () {return (area()*height);}
/ *private members of the base class cannot be accessed by the derived
class*/
//int volume () {return (width*length*height);}
};

7
INHERITANCE:
int main(){
Rectangle rect;
Box box;

rect.set_width(3);
rect.set_length(4);

box.set width(3); //inherited


box.set_length(4); //inherited
box.set_height(5);

cout<<“Rectangle area: ”<<rect.area()<<endl;


cout<< “Box base area: base area: ”<<box.area()<<endl; //inherited
cout<<“Box volume: ”<<box.volume()<<endl;
return 0;
8
}
INHERITANCE: DERIVED CLASS
class Box: private Rectangle {
int height;
public:
void set_height (int h){height=h;}
int volume () {return (area()*height);}
};

9
INHERITANCE
int main(){
Rectangle rect;
Box box;

rect.set_width(3);
rect.set_length(4);

//box.set width(3);
//box.set_length(4);
box.set_height(5);

cout<<“Rectangle area: ”<<rect.area()<<endl;


/* function area() is private to Box object cannot be accessed outside Box object */
//cout<< “Box base area: base area: ”<<box.area()<<endl;
cout<<“Box volume: ”<<box.volume()<<endl;
return 0;
} 10
INHERITANCE: BASE CLASS
#include <iostream>
using namespace std;
class Rectangle {
protected:
int width, length;
public:
void set_width(int w) {width=w;}
void set_length(int l) {length=l;}
int area() {return (width*length);}
};

11
INHERITANCE: DERIVED CLASS
class Box: public Rectangle {
int height;
public:
void set_height (int h){height=h;}
/*protected members of the base class can be accessed by the derived class */
int volume () {return (width*length*height);}
};

12
INHERITANCE
int main(){
Rectangle rect;
Box box;

rect.set_width(3);
rect.set_length(4);

box.set width(3); //inherited


box.set_length(4); //inherited
box.set_height(5);

cout<<“Rectangle area: ”<<rect.area()<<endl;


cout<< “Box base area: ”<<box.area()<<endl; //inherited
cout<<“Box volume: ”<<box.volume()<<endl;
return 0;
13
}
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
 Both base class and derived class can have constructors and
destructors

 Constructor functions are executed in the order of derivation


 Destructor functions are executed in the reverse order of derivation

 While working with an object of a derived class, the base class


constructor and destructor are always executed no matter how the
inheritance was done (private, protected or public)

14
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
class base { void main() {
public: derived obj;
base() {
}
cout << “Constructing base class\n”;
}
~base() { Output:
cout << “Destructing base class\n”; Constructing base class
} Constructing derived class
};
Destructing derived class
class derived : public base {
Destructing base class
public:
derived() {
cout << “Constructing derived class\n”;
}
~derived() {
cout << “Destructing derived class\n”;
}
15
};
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
 If a base class constructor takes parameters then it is the
responsibility of the derived class constructor(s) to collect them and
pass them to the base class constructor using the following syntax -
 derived-constructor(arg-list) : base(arg-list) { … }
 Here “base” is the name of the base class

 It is permissible for both the derived class and the base class to use
the same argument
 It is also possible for the derived class to ignore all arguments and
just pass them along o the base class.

16
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
#include <iostream>
using namespace std;

class Rectangle {
int *width, *length;
public:
Rectangle();
Rectangle(int, int);
~Rectangle ();
int area () {return (*width * *length);}
};

Rectangle::Rectangle () {
width= new int;
length = new int;
*width = 0;
*length = 0;
17
}
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
Rectangle::Rectangle (int a, int b) {
width= new int;
length = new int;
*width = a;
*length = b;
}

Rectangle:: ~Rectangle () {
delete width;
delete length;
}

18
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
class Box: public Rectangle{
int *height;
public:
Box();
Box(int, int, int);
~Box();
int volume(){ return area()*(*height);}
};

Box::Box ()
{
height=new int;
height=0;
} 19
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
Box::Box (int w, int l, int h):Rectangle(w,l) {
height=new int;
height=h;
}

Box::~Box () {
delete height;
}

20
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
int main(){
Rectangle rect(3,4);
Box box (3,4,5);

cout<<“Rectangle area: ”<<rect.area()<<endl;


cout<< “Box base area: base area:”<<box area()<<endl;
cout<<“Box volume: ”<<box.volume()<<endl;

return 0;
}

21
CONSTRUCTORS, DESTRUCTORS, AND INHERITANCE
class MyBase { void main() {
public: MyDerived o1; // x = 0, y = 0
int x;
MyDerived o2(5); // x = 5, y = 0
MyBase(int m) { x = m; }
}; MyDerived o3(6, 7); // x = 6, y = 7
class MyDerived : public MyBase { }
public:
int y;
MyDerived() : MyBase(0) { y = 0; }
MyDerived(int a) : MyBase(a)
{
y = 0;
}
MyDerived(int a, int b) : MyBase(a)
{
y = b;
}
22
};
MULTIPLE INHERITANCE
 A derived class can inherit more than one base class in two ways
 By a chain of inheritance
 b1 -> d1 -> dd1 -> ddd1 -> …

 Here b1 is an indirect base class of both dd1 and ddd1 b1


 Constructors are executed in the order of inheritance

 Destructors are executed in the reverse order


d1

dd1

ddd1 23
MULTIPLE INHERITANCE
 A derived class can inherit more than one base class in two ways
 By directly inheriting more than one base class
 class d1 : access b1, access b2, …, access bN { … }

 Constructors are executed in the order, left to right, that the


base classes are specified
 Destructors are executed in the reverse order

b1 b2 b3

d1 24
MULTILEVEL CLASS HIERARCHY
class Point{
double x; double x;
double y;
public:
Point(double x, double y){this Point(double x, double y){
this->x=x;
this->y=y;
}
void get_xy(double &x, double &y){
x=this->x;
y=this->y;
}
}
25
MULTILEVEL CLASS HIERARCHY
class Circle: public Point{
protected:
double rad;
public:
Circle(double x, double y, double r);
double area(){return 3.14*rad*rad;}
}

Circle::Circle(double x, double y, double r):Point(x,y){


rad=r;
}

26
MULTILEVEL CLASS HIERARCHY
class Cylinder: public Circle{
double height;

public:
Cylinder(double x, double y, double r, double h);
double volume(){return 3.14*rad*rad*height;}
}

Cylinder::Cylinder(double x, double y, double r, double h):Circle(x,y,r){


height=h;
}

27
MULTIPLE DIRECT INHERITANCE
class Point{
double x;
double y;
public:
Point(double x, double y){this->x=x; this->y->y;}
void get_xy(double &x, double &y){x=this->x, y=this->y;}
}

28
MULTIPLE DIRECT INHERITANCE
class Circle{
protected:
double rad;
public:
Circle(double r) {rad=r;}
double area(){return 3.14*rad*rad;}
}

29
MULTIPLE DIRECT INHERITANCE
class Cylinder: public Point, public Circle{
double height;
public:
Cylinder(double x, double y, double r, double h);
double volume(){ return 3.14*rad*rad*height;}
}
Cylinder::Cylinder(double x, double y, double r, double h):Point(x,y),Circle(r)
{
height=h;
}

30
MULTIPLE INHERITANCE: VIRTUAL BASE CLASS
 Virtual Base Class prevents a derived class to inherit more than one
copy of the base class
 This may happen when a derived class directly inherits two base
classes and these base classes are also derived from another common
base class
Base Base

D1 D2

31

D3
MULTIPLE INHERITANCE: VIRTUAL BASE CLASS
class Base { class D3 : public D1, public D2 {
public: // contains two copies of ‘i’
int i; };
};
class D1 : public Base { void main() {
public: D3 obj;
int j; obj.i = 10; // ambiguous, compiler error
}; obj.j = 20; // no problem
class D2 : public Base { obj.k = 30; // no problem
public: obj.D1::i = 100; // no problem
int k; obj.D2::i = 200; // no problem
}; }

32
MULTIPLE INHERITANCE: VIRTUAL BASE CLASS
class Base { class D3 : public D1, public D2 {
public: // contains only one copy of ‘i’
int i; }; // no change in this class definition
};
class D1 : virtual public Base { void main() {
public: D3 obj;
int j; obj.i = 10; // no problem
}; // activity of D1 not affected obj.j = 20; // no problem
class D2 : virtual public Base { obj.k = 30; // no problem
public: obj.D1::i = 100; // no problem, overwrites ‘10’
int k; obj.D2::i = 200; // no problem, overwrites ‘100’
}; // activity of D2 not affected }

33
FUNCTION OVERRIDING
 Giving new implementation of base class method into derived class is
called function overriding
 Signature of base class method and derived class must be same
Signature involves:
 Number of arguments
 Type of arguments
 Sequence of arguments

34
FUNCTION OVERRIDING
#include <iostream>
using namespace std;
class Point{
protected:
double x;
double y;
public:
Point() {x=0.0; y=0.0;}
Point(double x, double y);
double area(){return 0;}
};

Point::Point(double x, double y){


this->x=x; this->y=y; 35
}
FUNCTION OVERRIDING
class Circle: public Point{
protected:
double rad;
public:
Circle(){rad=0.0;}
Circle(double x double y double r);
double area();
};

Circle::Circle(double x, double y, double r) : Point(x,y) {


rad=r;
}
double Circle::area(){
return 3.14*rad*rad; 36
}
FUNCTION OVERRIDING
class Cylinder:public Circle{
double height;
public:
Cylinder(){height=0.0;}
Cylinder(double x, double y, double r, double h);
double area();
};
Cylinder::Cylinder(double x, double y, double r, double h): Circle(x,y,r){
height=h;
}

double Cylinder::area(){
return 3.14*rad*rad*height;
} 37
FUNCTION OVERRIDING
int main(){

Point p(1.0, 1.0);


Circle c(1.0, 1.0, 3.0);
Cylinder cl(1.0, 1.0, 3.0, 2.0);

cout<<"The area of the point is: "<<p.area()<<endl;


cout<<"The area of the circle is: "<<c.area()<<endl;
cout<<"The area of the cylinder is: "<<cl.area()<<endl;

return 0;
}

38
POLYMORPHISM IN C++
 Compile time polymorphism
 Uses static or early binding
 Example: function and operator overloading
 Run time polymorphism

 Uses dynamic or late binding


 Example: virtual functions

39
EARLY BINDING VS. LATE BINDING
 Early binding
 Normal functions, overloaded functions, nonvirtual member and friend
functions
 Resolved at compile time
 Very efficient
 But lacks flexibility
 Late binding
 Virtual functions accessed via a base class pointer
 Resolved at run-time
 Quite flexible during run-time
 But has run-time overhead; slows down program execution

40
POINTERS TO DERIVED CLASSES
 C++ allows base class pointers to point to derived class objects
 Let we have –

 class base { … };
 class derived : public base { … };
 Then we can write –

 base *p1; derived d_obj; p1 = &d_obj;


 base *p2 = new derived;

41
POINTERS TO DERIVED CLASSES
 Using a base class pointer (pointing to a derived class object) we can
access only those members of the derived object that were inherited
from the base

 This is because the base pointer has knowledge only of the base class

 It knows nothing about the members added by the derived class

42
POINTERS TO DERIVED CLASSES
class base { void main() {
public: base b1;
void show() { b1.show(); // base
cout << “base\n”; derived d1;
} d1.show(); // derived
}; base *pb = &b1;
class derived : public base { pb->show(); // base
public: pb = &d1;
void show() { pb->show(); // base
cout << “derived\n”; }
}
};  All the function calls here are 43
statically/early bound
POINTERS TO DERIVED CLASSES
 While it is permissible for a base class pointer to point to a derived object,
the reverse is not true

base b1;
derived *pd = &b1; // compiler error

 We can perform a downcast with the help of type-casting, but should use it
with caution

 Pointer arithmetic is relative to the data type the pointer is declared as


pointing to
 If we point a base pointer to a derived object and then increment the
pointer, it will not be pointing to the next derived object
 It will be pointing to (what it thinks is) the next base object !!!
44
VIRTUAL FUNCTION
 A virtual function is a member function that is declared within a
base class and redefined (called overriding) by a derived class

 It implements the “one interface, multiple methods” philosophy that


underlies polymorphism

 The keyword virtual is used to designate a member function as


virtual

 Supports run-time polymorphism with the help of base class pointers

45
VIRTUAL FUNCTION
 While redefining a virtual function in a derived class, the function
signature must match the original function present in the base class
 So, we call it overriding, not overloading

 When a virtual function is redefined by a derived class, the keyword


virtual is not needed (but can be specified if the programmer wants)

 The “virtual”-ity of the member function continues along the


inheritance chain

 A class that contains a virtual function is referred to as a


polymorphic class
46
VIRTUAL FUNCTION
class base { void main() {
public: base b1;
virtual void show() { b1.show(); // base - (s.b.)
cout << “base\n”; derived d1;
d1.show(); // derived – (s.b.)
}
base *pb = &b1;
};
pb->show(); // base - (d.b.)
class derived : public base {
pb = &d1;
public: pb->show(); // derived (d.b.)
void show() { }
cout << “derived\n”;
}  Here,
 s.b. = static binding
};  d.b. = dynamic binding
47
VIRTUAL FUNCTION
class base { class d2 : public base {
public: public:
void show() {
virtual void show() {
cout << “derived-2\n”;
cout << “base\n”;
}
} };
}; void main() {
class d1 : public base { base *pb; d1 od1; d2 od2;
public: int n;
void show() { cin >> n;
cout << “derived-1\n”; if (n % 2) pb = &od1;
else pb = &od2;
}
pb->show(); // guess what ??
}; 48
}
VIRTUAL DESTRUCTORS
 Constructors cannot be virtual, but destructors can be virtual
 It ensures that the derived class destructor is called when a base
class pointer is used while deleting a dynamically created derived
class object

49
VIRTUAL DESTRUCTORS
class base { void main() {
public: base *p = new derived;
~base() { delete p;
cout << “destructing base\n”; }
}
};  Output:
 destructing base
class derived : public base {
public:
~derived() {
cout << “destructing derived\n”;
}
}; 50
VIRTUAL DESTRUCTORS
class base { void main() {
public: base *p = new derived;
virtual ~base() { delete p;
cout << “destructing base\n”; }
}
};  Output:
 destructing derived
class derived : public base {
 destructing base
public:
~derived() {
cout << “destructing derived\n”;
}
}; 51
PURE VIRTUAL FUNCTIONS
 If we want to omit the body of a virtual function in a base class, we
can use pure virtual functions
 virtual ret-type func-name(param-list) = 0;
 It makes a class an abstract class

 We cannot create any objects of such classes

 It forces derived classes to override it


 Otherwise they become abstract too

 We can still create a pointer to an abstract class


 Because it is at the heart of run-time polymorphism
52
Acknowledgement
http://faizulbari.buet.ac.bd/Courses.html
http://mhkabir.buet.ac.bd/cse201/index.html

THE END

You might also like