56
Inheritance – Derived Classes

Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Embed Size (px)

Citation preview

Page 1: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Inheritance – Derived Classes

Page 2: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Employee Inheritance Hierarchy

Employee

HourlyEmp SalariedEmp

derived classes

base class

Page 3: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Derived Classes

Derived classes are used to create a class hierarchy.

The superclass is called the base class.

The subclass is called the derived class.

Friendship is not inherited.

Page 4: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Specifying Inheritance

In the class declaration, we follow

class name

with

:superclass

or

:private superclass

or

:public superclass

Page 5: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Employee Inheritance Example

class Employee

{

public:

Employee( );

Employee(int emp_id, char *emp_name);

Employee(const Employee &e);

~Employee( );

float calculate_pay( );

void set_tax_rate(float new_rate);

void print( );

protected:

float gross_pay;

private:

int id;

char *name;

float tax_rate;

};

Page 6: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Employee Inheritance Example (Continued)

class HourlyEmp : public Employee

{

public:

HourlyEmp( );

HourlyEmp(int emp_id, char *emp_name);

HourlyEmp(int emp_id, char *emp_name, float rate);

HourlyEmp(const HourlyEmp &h);

~HourlyEmp( );

float calculate_pay( );

void set_hours(float worked);

void set_pay_rate(float rate);

void print( );

private:

float hours_worked;

float pay_rate;

};

Page 7: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Member Visibility

Class members are divided into three categories of accessibility:

private member Can be accessed only by the member functions

and

friends of its class

protected member Behaves as a public member to a derived class; it

behaves as a private member to the rest of the

program.

public member Is accessible from anywhere within a program.

Page 8: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Inheritance and Visibility

Private inheritance changes the visibility of the base class members inherited

by the derived class:

private member remains private in the derived class and is not

accessible by the derived class methods

protected member becomes private in the derived class

public member becomes private in the derived class

When public inheritance is used, the visibility of the base class members is not

changed in the derived class

Page 9: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Storage Layout for Class Instances

base classdata

derived classdata

Page 10: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Visibility between Objects of the Same Class

What can an object access within ITSELF and other objects of the SAME

CLASS? [What part of Y can Z access?]

A

B

B Y, Z;

Base class parts(A part of Y)publicprotectedprivate

Derived class parts(B part of Y)publicprotectedprivate

Public inheritance Private inheritance

YYn

YYY

YYn

YYY

Page 11: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Visibility between Base and Derived Class Object

What parts of an object can be accessed by another object of a DERIVED

class? [What part of Y can be accessed by Z?]

A

B

B Z;A Y;

Base class parts(A part of Y)publicprotectedprivate

There is no B part of Y !

Public inheritance Private inheritance

YYn

Ynn

Page 12: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

External Visibility

A

B

B Z;

Base class parts(A part of Y)publicprotectedprivate

Derived class parts(B part of Y)publicprotectedprivate

Public inheritance Private inheritance

Ynn

Ynn

nnn

Ynn

What parts of an object can be accessed from OUTSIDE its inheritance

hierarchy? [What part of Z can be accessed from main?]

Page 13: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Visibility of Members Example

class A

{

public:

int a1;

void fa( ) { a1 = a2 = a3 = 0; }

protected:

int a2;

private:

int a3;

};

main( )

{

A x;

x.a1 = 1;

x.a2 = 1;

main( ) cannot access A::a2: protected member

x.a3 = 1;

main( ) cannot access A::a3: private member

}

Page 14: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Visibility of Members Example (Continued)

class B : public A

{

public:

int b1;

void fb( );

protected:

int b2;

private:

int b3;

};

void B::fb( )

{

b1 = b2 = b3 = 0;

a1 = 1;

a2 = 2;

a3 = 3;

B::fb() cannot access A::a3: private member

}

Page 15: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Visibility of Members Example (Continued)

main( )

{

B y;

y.a1 = 2;

y.fa( );

y.a2 = 2;

main( ) cannot access A::a2: protected member

y.a3 = 2;

main( ) cannot access A::a3: private member

y.b1 = 2;

y.b2 = 2;

main( ) cannot access B::b2: protected member

y.b3 = 2;

main( ) cannot access B::b3: private member

}

Page 16: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Visibility of Member Example (Continued)

class C : private A

{

public:

int c1;

void fc( );

protected:

int c2;

private:

int c3;

};

void C::fc( )

{

c1 = c2 = c3 = 0;

a1 = 1;

a2 = 2;

a3 = 3;

C::fc() cannot access A::a3: private member

}

Page 17: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Visibility of Members Example (Continued)

The following statements cause the indicated compiler errors:

main( )

{

C z;

z.a1 = 3; //z.fa(); would be similar

main( ) cannot access a1: A is a private base class

z.a2 = 3;

main() cannot access A::a2: protected member

z.a3 = 3;

main() cannot access A::a3: private member

z.c1 = 3;

z.c2 = 3;

main() cannot access C::c2: protected member

z.c3 = 3;

main() cannot access C::c3: private member

}

Page 18: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Summary of Access Rules for C++

C++ provides function and data protection through a combination of the

following:

public, private, and protected class members

inheritance

friendship

Page 19: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Invoking Parent Class Constructors

In the constructor for a derived class, its parent’s constructor may be passe

d data by putting

: BaseClassName (arguments)

after the function header. For example,

SalariedEmp (int id, char *name) : Employee(id, name) { }

This allows the base class part of the object to be initialized at object constr

uction.

The parent’s constructor is always invoked before the body of the derived

class constructor

Page 20: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Employee Constructor Examples

Employee::Employee( ) : id(0), tax_rate(0)

{

name = strdup(“”);

gross_pay = 0;

}

Employee::Employee (int emp_id, char *emp_name)

{

id = emp_id;

name = strdup(emp_name);

gross_pay = tax_rate = 0;

}

Employee::Employee (const Employee& e)

{

id = e.id;

name = strdup(e.name);

gross_pay = e.gross_pay;

tax_rate = e.tax_rate;

}

Page 21: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Employee Constructor Examples (Continued)

HourlyEmp::HourlyEmp( )

{

hours_worked = pay_rate = 0;

}

HourlyEmp::HourlyEmp(int emp_id, char *emp_name) : Employee(emp_id, emp_name)

{

hours_worked = pay_rate = 0;

}

HourlyEmp::HourlyEmp(int emp_id, char *emp_name, float rate) :Employee(emp_id, emp_name), pay_rate(rate), hours_worked(0)

{ }

HourlyEmp::HourlyEmp(const HourlyEmp& h) : Employee(h)

{

hours_worked = h.hours_worked;

pay_rate = h.pay_rate;

}

Page 22: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Inherited Functions

Member functions inherited from a public base class can be sent to

instances of a derived class.

An instance of a derived class can be passed as a parameter declared to be

an instance of a public base class from which it is derived.

A reference to a derived class can be passed as a parameter declared to be a

reference to an instance of a public base class from which it is derived.

A pointer to a derived class can be passed as a parameter declared to point

to an instance of a public base class from which it is derived.

Page 23: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Inherited Functions (Continued)#include <string.h>

void test_function(Employee);

main( )

{

Employee e1(101, “Chris”), e2;

HourlyEmp h1(102, “Kerry”), h2(103, “Lee”, 25.00);

h2.set_hours(41.0);

h2.set_tax_rate(0.18); // method inherited from Employee

cout << “Pay = “ << h2.calculate_pay() << endl;

test_function(e1);

test_function(e2);

}

void test_function(Employee x)

{

x.print( );

cout << endl;

}

Page 24: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Pointers to Class Instances

A pointer to a base type is allowed to point to an instance of a class derived

from it. This is not true if private inheritance was specified between the bas

e and derived classes.

Reference to a base class may also be assigned an instance of a class derive

d from it

To allow a pointer to a derived class to point to an instance of its superclas

s, it must be explicitly converted with an appropriate constructor or type co

nversion operator.

Page 25: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Pointers to Class Instances (Continued)

main( )

{

Employee e1(101, “Chris”), e2;

HourlyEmp h1(102, “Kerry”), h2(103, “Lee”, 25.00);

Employee *eptr;

HourlyEmp *hptr;

eptr = &e1;

hptr = &h2;

eptr = &h1; // base class ptr points to derived class object

// hptr = &e2; is not allowed

// hptr = eptr; is not allowed

eptr->print( ); // use the pointer to invoke Employee::print

hptr->print( ); // invoke HourlyEmp::print

hptr = (HourlyEmp *) eptr; // ok, but Dangerous!

}

Page 26: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Classes That Allocate Storage

Page 27: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Storage Allocation - New

This statement allocates storage for one object of type int.

int *ptr = new int;

This statement allocates storage for an array of ten objects of type int.

int *ptr = new int[10];

This statement allocates storage for one object of type Myclass. After storage

is allocated, the value 1024 is passed to the constructor and the storage is

initialized.

Myclass *ptr = new Myclass(1024);

Page 28: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Storage Allocation – New (Continued)

new is a unary operator that takes a type as its operand and returns a pointe

r to free storage sufficient to hold an instance of that type.

Vectors of objects may be allocated by using an array specifier in the opera

nd of new.

When new fails, it calls the function pointed to by the pointer _new_handle

r. If no such pointer is found, it returns 0. The pointer can be explicitly set,

or the function set_new_hander can be called.

new can be overloaded.

Page 29: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

set_new_handler

#include <new.h>

void noSpace( )

{

cerr << “New Failed” << endl;

exit(1);

}

main( )

{

set_new_handler(noSpace);

}

Page 30: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Polygon Class Description

Polygons are geometric figures with one or more sides. They have the

following methods:

A constructor that takes the number of sides and allocates storage for them.

A void constructor that sets the number of sides to 0.

A method to assign the length of the side of a polygon.

A method to compute the perimeter of a polygon.

A method to print the polygon.

A method to compute the area of a polygon.

Page 31: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Polygon Class

class Polygon // implements geometric shapes of 1 or more sides.

{ // uses ints to represent the lengths of the sides.

public:

Polygon( );

Polygon(int n_sides);

void assignSide(int which_side, int len);

int perimeter( );

void print( );

int area( );

protected:

int *sides;

private:

int num_sides;

};

Page 32: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Polygon Class (Continued)

Polygon::Polygon(int n_sides)

{

num_sides = n_sides;

sides = new int [num_sides];

for(int i = 0; i < num_sides; i++)

assignSide(i,0);

}

Polygon::Polygon()

{

num_sides = 0;

sides = NULL;

}

Page 33: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Polygon Class (Continued)

void Polygon::assignSide(int which_side, int len)

{

if(which_side < num_sides)

sides[which_side] = len;

else

cerr << “assignSide: value out of range” << endl;

}

int Polygon::perimeter( )

{

int sum = 0;

for (int i = 0; i < num_sides; i++)

sum += sides[i];

return sum;

}

Page 34: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Polygon Class (Continued)

int Polygon::area( )

{

cerr << “Area undefined for generic polygon” << endl;

return 0;

}

void Polygon::print( )

{

cout << “A polygon with sides : “ << endl << “\t”;

for(int i = 0; i < num_sides; i++)

cout << “ “ << sides [i];

}

Page 35: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Using the Polygon Class

Polygon triangle(3);

main()

{

int side;

for (int i = 0; i < 3; i++)

{

cin >> side;

triangle.assignSide(i, side);

}

cout << triangle.perimeter( );

}

Page 36: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Storage Allocation - Delete

delete is a unary operator that is applied to a pointer returned by new. It ex

plicitly deallocates the storage pointed to by the pointer.

For arrays of user-defined objects, use the following form:

delete [ ] pointer;

This ensures that the destructor is called for each element of the array.

The compiler cannot distinguish a pointer to a vector from a pointer to a si

ngle object.

delete can be overloaded

Page 37: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Polygon Class Destructor

Polygon::~Polygon( )

{

delete sides;

}

Page 38: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Memberwise Assignment Polygons

Polygon pentagon(5), triangle(3);

Polygon aShape;

aShape = triangle;

5

5

5

pentagon

triangle

aShape

Page 39: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Overloading =

Polygon& Polygon::operator = (Polygon& p)

{

if(this != &p) {

int *new_sides = new int[p.num_sides];

for(int i = 0; i < p.num_sides; i++)

new_sides[i] = p.sides[i];

delete sides;

sides = new_sides;

num_sides = p.num_sides;

}

return (*this);

}

Page 40: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Assignment versus Initialization

Assignment and initialization are not the same.

A user-defined assignment operator is not applied to an uninitialized object.

Initialization (the copy constructor) is used when class instances are initiali

zed in declarations, for passing instances as function arguments, and for ret

urning instances from functions.

Page 41: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

The Copy Constructor

Polygon::Polygon(const Polygon& p)

{

num_sides = p.num_sides;

sides = new int [num_sides];

for (int i = 0; i < num_sides; i++)

sides[i] = p.sides[i];

}

Page 42: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Example of Constructor Invocation

Polygon test(Polygon p) // passing a to test: copy constructor

{

return p; // return Polygon from test: copy constructor

}

main()

{

Polygon a(5); // 1-parameter constructor

Polygon b = Polygon(3); // 1-parameter constructor (Polygon b(3))

Polygon c = a; // copy constructor

Polygon d; // void constructor

d = test(a); // assign result of test to d: assignment operator

// destruct function argument: destructor

// destruct temporary function result: destructor

} // destruct d, c, b, a : destructor

Page 43: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Classes Allocating Storage

When a class dynamically allocates storage, each of the following is necess

ary in the class:

regular constructor(s)

destructor

overloaded assignment operator

copy constructor

Page 44: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Default Memberwise Copy

If class does not provide an overloaded assignment operator or copy constr

uctor, when assignment or copying of instances is done, each base class an

d member class object in it has

its assignment operator or copy constructor invoked, if it exists

memberwise copy applied otherwise

Page 45: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Default Memberwise Copy (Continued)

If a class does provide an overloaded assignment operator or copy

constructor, it is invoked when assignment or copying of instances is done.

It is the responsibility of the class operators to invoke the base class or

member class operators, or both, as necessary.

If both a derived class and a base class define assignment operators and a

derived class object is assigned to a base class object, the type of the left-

hand operand determines the assignment operator used.

Page 46: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Virtual Functions

Page 47: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Polygon Class

class Polygon // implements geometric shapes of 1 or more sides.

{ // uses ints to represent the lengths of the sides.

public:

Polygon( );

Polygon(int n_sides);

void assignSide(int which_side, int len);

int perimeter( );

void print( );

int area( );

protected:

int *sides;

private:

int num_sides;

};

Page 48: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

A Polygon Hierarchy

Polygon

Triangle Rectangle

Square

Page 49: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Using the Polygon Classes

Polygon p1(5);

Triangle t1, t2(10, 10, 10);

Rectangle r1, r2(10, 20);

Square s1, s2(10);

p1.assignSide(0, 99);

cout << t2.perimeter() << endl;

t2.print(); cout << endl;

cout << r2.area() << endl;

r2.print(); cout << endl;

cout << s2.area() << endl;

s2.print(); cout << endl;

Page 50: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Accessing Polygons through Pointers

Polygon *p[50];

Triangle t1, t2(10, 10, 10);

Rectangle r1, r2(10, 20);

Square s1, s2(10);

p[0] = &t1;

p[1] = &r2;

p[2] = &s2;

cout << p[i]->area() << endl;

p[i]->print();

Page 51: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Accessing Polygons through Pointers (Continued)

Polygon

Triangle Rectangle

Square

The code for print() and area()is found in this class

Page 52: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Virtual Functions

If we change the declaration of the function area in Polygon to

virtual int area( );

And the declaration of function print in Polygon, to

virtual void print( );

Then print and area are dynamically bound to the code, appropriate to the

object to which they are sent.

Page 53: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Virtual Function (Continued)

Polygon

Triangle Rectangle

Square

The code for p[1]->print( ), andp[1]->area( ), is found in this class

The code for p[0]->print( ), andp[0]->area( ), is found in this class

The code for p[2]->print( ), andp[2]->area( ), is found in this class

Page 54: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Virtual Function (Continued)

The keyword virtual is specified once for the inheritance hierarchy by placi

ng it in the root of the tree or subtree. It is used to dynamically bind a mem

ber function to the appropriate code, based on the type of the receiver.

The derived classes can redefine the virtual function or inherit it. They can

also define additional virtual functions.

The access level (public, private, or protected) is specified by the type thro

ugh which it is invoked.

Page 55: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Pure Virtual Functions

In a base class, the virtual function declaration can be specified as follows:

virtual retType name(arguments) = 0;

This function is called a pure virtual function. The class declaring it is calle

d an abstract class.

It is illegal to create instances of classes containing one or more pure virtua

l function declarations.

A pure virtual function that is not redefined in a derived class will be inheri

ted as a pure virtual function, and the derived class will become an abstract

class.

Page 56: Inheritance – Derived Classes. Employee Inheritance Hierarchy Employee HourlyEmp SalariedEmp derived classes base class

Virtual Destructors

Given pointers to a base class (which may point to instances of the derived

classes), if we delete them, we invoke the destructor for the base class. To

overcome this, we use virtual destructors.

To declare a destructor as virtual, precede its declaration with the keyword

virtual, in the base class.

Even though destructors in a derived class don’t have the same name as in

the base class, they can still be declared virtual.