0% found this document useful (0 votes)
42 views58 pages

Constructors and Destructors STATIC ANF FRIEND FINAL

Uploaded by

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

Constructors and Destructors STATIC ANF FRIEND FINAL

Uploaded by

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

Constructor

Constructor is a special member function used in C++ programming languages. It is different in


principal and implementation when compared other normal member functions of a class. It is good
programming practice to have at least one constructor function in each class. Following are some of
the features of constructor function that makes it different from other member functions of
class.
1. Return Type- constructor function does not have a return type and it is mandatory for any other
member function of the class. Void is also a data type and is used when the member function does not
return any value. So the construct function does not mention any thing for the return type.
2. Name or identifier- Identifier of the member function cannot be same as identifier used for any
other type. But the name of the constructor function is same as the name of the class. For example, if
you define as class named student, the name of the constructor function will also be student.
3. Function call- In order to call a member function of a class, you need to write a function call
statement explicitly. Whereas a constructor function is called automatically when the object of the
same class is created. You can also call the constructor function by explicitly calling is using a
function call statement, but it is not mandatory.
4- Objective- Objective of the constructor function is to initialize the data members of the class. You
are not allowed to define the data members when they are declared in C++.
5. different types of constructors can be created and one class can have more than one constructor. It
is also called overloading of constructor function.

7.3 Types of constructors


In C++ you can create four types of constructors.

7.3.1 Default constructor


It is the simplest type of constructor with no arguments. Following is the syntax of default
constructor:
Class_Name ( )
Class name is also the name of the constructor function.

Program 1
To implement default constructor

//header files
#include <iostream.h>
#include<conio.h>
//definition of class
class DEFAULT
{
private:
int var1;
int var2;
public:
//default constructor
DEFAULT ( )
{
var1= 0;
var2= 0;
}
void input ( )
{
cout<<”\nEnter value for data member var1 :- “;
cin>>var1;
cout<<”\nEnter value for data member var2 :- “;
cin>>var2;
}
void display( )
{
cout<<”\nValue of data member var1 :- “<<var1;
cout<<”\nValue of data member var2 :- “<<var2;
}
};

void main( )
{
// object of class DEFAULT
DEFAULT obj1, obj2;
//call to member function of obj2
cout<<"\nObject 2";
obj2.input( );
// call to member function of obj1
cout<<"\nObject 1";
obj1.display();
// call to member function of obj2
cout<<"\nObject 2";
obj2.display();

getch();
}

Class in the last program consists of following constructor:


//default constructor
DEFAULT ( )
{
var1= 0;
var2= 0;
}
It is default constructor because it does not have any arguments. Also the name of the constructor is
same as the name of the class DEFAULT.

Output:
Object 2
Enter value for data member var1 :- 12
Enter value for data member var1 :- 17
Object 1
Value of data member var1 :- 0
Value of data member var2 :- 0
Object 2
Value of data member var1 :- 12
Value of data member var2 :- 17

Value for the data members of object 1 is 0 because the data members are initialized using constructor
function to 0 and no changes are made to the same.

7.3.2 Parameterized constructor


This is the second type of constructor that consists of arguments in the argument list. Not always you
want to initialize the data members of a class to 0 or some fix value. You may also want to allow the
user to pass the initialization value of the data members to the constructor function. The same can be
achieved by creating a parameterized constructor and passing initialization value as arguments to the
constructor. Following is the syntax of parameterized constructor:
Class_Name (Argument_List )
Argument list may consist of one or more formal arguments.

Program 2
To implement parameterized constructor

//header files
#include <iostream.h>
#include<conio.h>
//definition of class
class PARAMETER
{
private:
int var1;
int var2;
public:
//parameterized constructor
PARAMETER ( int a, int b)
{
var1= a;
var2= b;
}
PARAMETER ( )
{
var1= 0;
var2= 0;
}

void display( )
{
cout<<”\nValue of data member var1 :- “<<var1;
cout<<”\nValue of data member var2 :- “<<var2;
}
};

void main( )
{
// object of class DEFAULT
PARAMETER obj1(13, 16), obj2;
// call to member function of obj1
cout<<"\nObject 1";
obj1.display();
// call to member function of obj2
cout<<"\nObject 2";
obj2.display();

getch();
}

Class in the last program consists of following parameterized constructor:


//parameterized constructor
PARAMETER ( int a, int b)
{
var1= a;
var2= b;
}
It is parameterized constructor because it consists of two arguments. The same is called twice when
the two objects of the same class are created in function main().
DEFAULT obj1(13, 16), obj2;
Two actual arguments passed to the constructor function for obj1 are 13 and 16 which are assigned to
two data members of obj1 respectively.
Similarly two actual arguments passed to the constructor function for obj2 are 20 and 30 which are
assigned to two data members of obj2 respectively.

Output:
Object 1
Value of data member var1 :- 13
Value of data member var2 :- 16
Object 2
Value of data member var1 :- 0
Value of data member var2 :- 0

7.3.3 Default argument constructor


Next type of constructor also consists of arguments in the argument list. But it is different from
parameterized constructor. The default argument constructor consists of more formal arguments than
the actual arguments that are passed to the constructor. Some of the formal arguments in the
constructor function consists of the default value.

Class_Name (Argument1, Argument2 = value )

Program 3
To implement default argument constructor

//header files
#include <iostream.h>
#include<conio.h>
//definition of class
class DEFAULT_ARGUMENT
{
private:
int var1;
int var2;
public:
//default argument constructor
DEFAULT_ARGUMENT ( int a, int b = 5)
{
var1= a;
var2= b;
}
void display( )
{
cout<<”\nValue of data member var1 :- “<<var1;
cout<<”\nValue of data member var2 :- “<<var2;
}
};

void main( )
{
// object of class DEFAULT_ARGUMENT
DEFAULT_ARGUMENT obj1(13), obj2 (20);
// call to member function of obj1
cout<<"\nObject 1";
obj1.display();
// call to member function of obj2
cout<<"\nObject 2";
obj2.display();
getch();
}

Class in the last program consists of following default argument constructor:


//default argument constructor
DEFAULT_ARGUMENT ( int a, int b = 5)
{
var1= a;
var2= b;
}
It is called default argument constructor because it consists of two arguments and the second
argument is assigned a default value. The same is called twice when the two objects of the same class
are created in function main( ).
DEFAULT_ARGUMENT obj1(13), obj2 (20);
Only one argument 13 is passed to the constructor function for obj1 which is passed to formal
argument 'a' and 'b' takes the default value of 5.
Similarly one argument 20 is passed to the constructor function for obj2 which is passed to formal
argument 'a' and 'b' takes the default value of 5.
Output:
Object 1
Value of data member var1 :- 13
Value of data member var2 :- 5
Object 2
Value of data member var1 :- 20
Value of data member var2 :- 5

7.3.4 Copy constructor


Last constructor is called copy constructor. In this type of constructor reference of an object is
passed as argument to the constructor function. Copy constructor is used to initialize one object
using the reference of another object. Syntax of copy constructor is a follows:
Class_Name (Class_name &Object_Name)

Program 4
To implement copy constructor

//header files
#include <iostream.h>
#include<conio.h>
//definition of class
class COPY
{
private:
int var1;
int var2;
public:
//default constructor
COPY ()
{
var1= 0;
var2= 0;
}
//copy constructor
COPY (COPY &obj3)
{
var1= obj3.var1;
var2= obj3.var2;
}
void input ( )
{
cout<<”\nEnter value for data member var1 :- “;
cin>>var1;
cout<<”\nEnter value for data member var2 :- “;
cin>>var2;
}
void display( )
{
cout<<”\nValue of data member var1 :- “<<var1;
cout<<”\nValue of data member var2 :- “<<var2;
}
};

void main( )
{
// object of class COPY
COPY obj1;
// call to member function of obj1
cout<<"\nObject 1";
obj1.input();
// object of class COPY
COPY obj2(obj1);
// call to member function of obj1
cout<<"\nObject 1";
obj1.display();
// call to member function of obj2
cout<<"\nObject 2";
obj2.display();
getch();
}

Class in the last program consists of two constructor functions. One is default constructor because no
arguments are passed to the constructor function when obj1 is created.

//default constructor
COPY ()
{
var1= 0;
var2= 0;
}

For the following statement:


// object of class COPY
COPY obj1;
Second is copy constructor which is called when obj2 is created. Reference of obj1 is passed as
argument to the copy constructor.

//copy constructor
COPY (COPY &obj3)
{
var1= obj3.var1;
var2= obj3.var2;
}
For the following statement:
// object of class COPY
COPY obj2(obj1);

Output:
Object 1
Enter value for data member var1 :- 12
Enter value for data member var1 :- 17
Object 1
Value of data member var1 :- 12
Value of data member var2 :- 17
Object 2
Value of data member var1 :- 12
Value of data member var2 :- 17

Data members of the obj2 are initialized using the obj1 and that is why the output for both the objects
is same.

7.4 Destructors
Destructor is another special member function in C++ programming language. It is also automatically
called and there is no need to explicitly call it using a function call statement. Contrary to constructor
which is called automatically when the object of the same class is created, destructor is automatically
called when the object of that class is destroyed. Destructor has a great significance in C++ and it is
good programming practice to make use of the same when working with classes. Following are some
of the characteristics of destruction function in C++:
1. Automatically called: destructor function is automatically called when the object of the same class
is destroyed.
2. Single destructor- unlike construction member function, you can only have one destruction function
in a single class and there are no different types of destructors.
3. Naming- destructor naming is slightly different from construction function. It also shares the name
of the class to which it belongs to, but it is preceded by the symbol ~.
4. Objective- destruction function is mainly used to free if any dynamic memory is allocated for the
class during run time. It is also used to decrement the counting of the objects if some variable is used
to maintain the count of objects created for the class.
5. Stack Implementation- The objects as they are created are stored in a stack data structure and if all
objects are destroyed at once, the objects are destroyed in the reverse order as stack is a last in first out
based data structure.
Syntax for defining the destructor function:
~ Class_Name ( )
{
}

Program 5
To implement the concept of destructor

//header files
#include <iostream.h>
#include<conio.h>
//definition of class
class DESTRUCTOR
{
private:
int var1;
public:
//constructor
DESTRUCTOR ( int a)
{
var1= a;
cout<<"\nObject number "<<var1<<" is created";
}
//destructor
~ DESTRUCTOR ()
{
cout<<"\nObject number "<<var1<<" is destroyed";
}
};

void main( )
{

// objects of class DESTRUCTOR


DESTRUCTOR obj1(1);
DESTRUCTOR obj2(2);
DESTRUCTOR obj3(3);

//all object destroyed


getch();
}

Class consists of a constructor function that is used to initialize or set the data member of the object to
the number of objects already created. It kinds of gives the token number to the newly created object:
DESTRUCTOR ( int a)
{
var1= a;
cout<<"\nObject number "<<var1<<" is created";
}

When all the objects are destroyed, a message is displayed to show the token number of the object
being destroyed.

Output:
Object number 1 is created
Object number 2 is created
Object number 3 is created
Object number 3 is destroyed
Object number 2 is destroyed
Object number 1 is destroyed

As you can observe that the object's are getting destroyed in the reverse order. i.e. the object with the
highest token number is being destroyed first.
7.5 Differences between Constructor and destructor

Constructor Destructor
1. It is automatically called when the object of It is automatically called when the object of the
the same is class is created. same is class is destroyed.
2. Name of the constructor function is same as Name of the destructor function is also same as
that of the class. that of the class, but it is preceded by ~ symbol.
3. You can create multiple constructor functions You can create only one destructor function for
for a single class. a single class.
4. Objective of using a constructor function is to Objective of using a destructor function is to
initialize the data members of the class. free any dynamically allocated memory during
run-time.

9.2 Static data member


Class is a collection of data members and member functions. When you create an object of a class,
copy of each data member is created for that object. When you create second object of a class,
additional copy of data members is created for the second object. Copy of data members for each
object is private to that object only and cannot be accessed by other objects.

Consider the following class structure for example,

Figure 9.1 "student" class structure


The class "student" consists of 5 data members and 3 member functions. The memory allocated to
member functions is shared amongst all objects of the class, but separate and private copies for data
members is allocated to each object of the class. For example, consider that 3 objects of the class
"student" are created.
Figure 9.2 Memory allocation for "student" class shown in figure 9.1
As you can see in the figure above, separate and private copy of all data members is allocated to each
class object, but a single copy of member functions is shared by all class objects.
What is static data member?
Static data member is also called class member. It is called so because only one copy of the static
data member is created irrespective of the number of objects created for the same class. It means, a
static data member is one for which only one copy in created which is shared by all objects of the
class. Consider the following structure of a class and its memory allocation in the subsequent figure:

Figure 9.3 "student" class structure with a static data member


The only difference between the structures of figure 9.1 and figure 9.3 is that the latter one includes a
static data member.
Figure 9.4 Memory allocation for "student" class shown in figure 9.3
As you can see in the figure above, only a single copy of the static data member is created which is
shared by all objects of the class similar to member functions.

9.2.1 Scope resolution operator


The normal data members of a given class can be accessed using a dot operator with object name to
which they belong. But a static data member does not belong to any object and it belongs to the class
itself. Hence it is accessed using a scope resolution operator along with the class name. Also the
normal data members are defined when the object of that class is created. If no object is created, data
member of the class are not defined. In case of static data members, there is no connection between
the creation of class objects and definition of static data members. Even if no object of the class is
created, the static data member can still be defined. The static data member needs to be defined
explicitly after the definition of the class.
Syntax to define the static data member:
Data_Type Class_Name:: Static_Data;
For example,
student::count;
the last statement is used to define the count static data member of the class student. The static data
member is declared in the class using the static keyword.
Initialization
Normal data member is defined when the object of that class is created. If no constructor function is
defined for that class, the normal data members are initialized with some garbage value. But in case of
static data member, when it is explicitly defined, it is automatically initialized with value 0.
Program 1
To count the number of active objects using static data member
//header files
# include < iostream.h >
# include < conio.h >
//definition of class
class ACTIVE
{
private:
public:
static int count ;
// constructor function
ACTIVE ( )
{
count++ ;
cout<<" \n Object number :- " << count << " created " ;
}
//destructor function
~ ACTIVE ( )
{
cout <<" \n Object no. “<<count<< “ destroyed. " ;
count -- ;

}
};

//definition of static variable


int ACTIVE::count ;

void main( )
{
// object of class ACTIVE
{
ACTIVE obj1 ;
{
ACTIVE obj2 ;
{
ACTIVE obj3 ;
}
}
//accessing static data member
cout<<" \n Objects remaining :- " << ACTIVE::count ;
}
cout<<" Objects remaining :- " << ACTIVE::count ;
getch( ) ;
}
Objects in the last program are intentionally created inside blocks or curly braces. Once the block
comes to an end, the object created inside the block is destroyed and hence the destructor function of
the same is called. When an object is created, the value of the static data member is incremented by 1
using the constructor function and when the object is destroyed, the value of the static data member is
decremented by one using the destructor function. Following statement is used to access the static
member with the help of scope resolution operator to display the count of currently active objects of
the class.
cout<<"\n Objects remaining :- "<<ACTIVE::count;

Output:
Object number :- 1 created
Object number :- 2 created
Object number :- 3 created
Object no. 3 destroyed.
Object no. 2. destroyed.
Objects remaining :- 1
Object no. 1 destroyed.
Objects remaining :- 0

PROGRAM 2
Attendance marking and use static data member

// header files
# include <conio.h>
# include <iostream.h>

// definition of class student


class student
{
private:
int roll_no, class_no, attendance ;

public:
//static data member
static int total;
//constructor function
Student ( )
{
roll_no = 0 ;
class_no = 0 ;
attendance = 0 ;
}
void input_details ( )
{
cout<<" \n Enter the students roll number:- " ;
cin>>roll_no ;
cout<<" Enter the students class :- " ;
cin>>class_no ;
}
void mark_attendance ( )
{
char temp ;
cout<<" Is the student present: (y / n ) ? " ;
temp = getche ( ) ;
if ( temp == 'y' )
{
attendance++ ;
}
}
void display_details ( )
{
cout<<" \n Students roll_no :- " << roll_no ;
cout<<" \n Students class:- " << class_no ;
cout<<" \n Students attendance :- " << attendance ;
}
};
//definition of static data member
int student::total ;
void main ( )
{
int days ;
// object of class student
student obj1 , obj2 ;
//member function called
cout<<" \n Student 1 " ;
obj1.input_details ( ) ;
cout<<" \n Student 2 " ;
obj2.input_details ( ) ;
cout<<" Number of days classes held :- " ;
cin>>days ;

//marking attendance
for ( int a = 1 ; a <= days ; a++ )
{
student::total++ ;
cout<<" \n Day :- " << student::total ;
cout<<" \n Student 1 " ;
obj1.mark_attendance( ) ;
cout<<" \n Student 2 " ;
obj2.mark_attendance( ) ;
}
//display record
cout<<"\n Total classes held :- " << student::total ;
obj1.display_details ( ) ;
obj2.display_details ( ) ;
getch( ) ;
}
Output:
Student 1
Enter the students roll number :- 1
Enter the students class :- 11
Student 2
Enter the students roll number :- 2
Enter the students class :- 11
Number of days classes held :- 3
Day :- 1
Student 1 Is the student present: (y / n ) ? y
Student 2 Is the student present: (y / n ) ? n
Day :- 2
Student 1 Is the student present: (y / n ) ? y
Student 2 Is the student present: (y / n ) ? n
Day :- 3
Student 1 Is the student present: (y / n ) ? n
Student 2 Is the student present: (y / n ) ? y
Total classes held :- 3
Students roll_no :- 1
Students class:- 11
Students attendance :- 2
Students roll_no :- 2
Students class:- 11
Students attendance :- 1

9.3 Static member functions


Just like a static data member, static function is also a special member function of the class. A static
member function can be prototyped with the help of the static keyword.

9.3.1 Features of static member functions


Following are the key properties of the static member function of the class:
1. Access to static Data members only- A static member function can access only the static data
members of a class. It cannot be used to access the other data members of the class. Attempting to
access normal members from within the definition of static member function will generate an error.
2. Invoking Static member function- A normal member function of the class is invoked using the
object of that class and dot or membership operator. Whereas a static member function is invoked
using the class name and the scope resolution operator.

9.3.2 Implementing static member functions


Following is the program to implement the static member function.
Program 1
To implement the concept of static member function

//header files
# include < iostream.h >
# include < conio.h >
//definition of class
class ACTIVE
{
private:
// static data member of the class
static int count ;
public:
// constructor function
ACTIVE ( )
{
count++ ;
cout<<" \n Object number :- " << count << " created " ;
}
//destructor function
~ ACTIVE ( )
{
count -- ;
cout <<" \n Object destroyed. " ;
}
// static member function of the class
static void display ( )
{
cout<<" \n Objects remaining :- " << count ;
}
};

//definition of static variable


int ACTIVE::count ;
void main( )
{
// object of class ACTIVE
{
ACTIVE obj1 ;
{
ACTIVE obj2 ;
{
ACTIVE obj3 ;
}
}
//accessing static member function of the class
ACTIVE::display ( ) ;
}
//accessing static member function of the class
ACTIVE::display ( ) ;
getch( ) ;
}
The last program consists of a class with a static member function:
static void display ( )
{
cout<<" \n Objects remaining :- " << count ;
}
The objective of the static member function is to display the value of the static data member. A static
data member cannot be used to access any data members of the class which are not static.
The objective of the program is same as that of the program 1 in this lesson. The static data function is
invoked using the following statement:
//accessing static member function of the class
ACTIVE::display ( ) ;
Where ACTIVE is the name of the class and display ( ) is a static function. A static member function
can be invoked with the help of the scope resolution operator as shown in the statement above.
Output:
Object number :- 1 created
Object number :- 2 created
Object number :- 3 created
Object destroyed.
Object destroyed.
Objects remaining :- 1
Object destroyed.
Objects remaining :- 0
8.2 Friend Function
The concept of friend function is associated with the data hiding or encapsulation property of
object oriented programming. You already known that a class is a collection of data members and
member functions. The data members of class are generally declared under private section so that data
members cannot be accessed directly from outside the definition of class and member functions are
declared under the public section. The idea behind declaring the member functions using public
specifier is to let the access members declared using private access specifierin the class, i.e. data
members through the member functions only.
C++ programming provides you with a feature that allows you to access members declared using
private access specifier in the class from outside the class. This feature is called a friend function.
The name has been chosen very wisely. You can make any function as a friend function of any class.
What is the need of creating a friend function? Some times when you are working on a project from
onsite or from remote system (away from the actual system) and there is some problem with the
program, it is not possible to migrate the whole system or for security and other reasons it may also
not be allowed to. Then the option is to make a function friend of a class that lets you access the
insights of the actual system from outside the class. i.e. from any remote place. Without having to
copy or migrate the whole system, you are still able to access the members declared using private
access specifier in the class.

8.3 Features of friend function


Following are some of the features of a friend function
1. Not a member function- Even though a friend function is allowed the access of members declared
using private access specifier in the class, it is not the member function of the class. It is a simple
function outside the boundaries of a class.
2. Object as argument- Friend function is usually passed an object of the class it is friend of and it
accesses the members declared using private access specifier in the class using that object only. It is
not compulsory, but it is a good programming practice to do so.
3. Prototyping inside the class definition- Prototyping or declaration of the friend function is done
inside the definition of the class it is friend of. Prototyping a friend function is similar to prototyping
any other simple function except one thing and that is to add keyword friend in front of the function
prototype statement.
4. A function may be a friend of many classes- A function can be friend of any number of classes.
Simply pass object of all classes it is friend of.
5. Invoking the friend function- A friend function can be invoked or called for execution without the
use of any class object. So there is no need of the dot operator to invoke friend function.
6. No restriction of access specifier- you can declare or prototype a friend function under any access
specifier and there is no restriction on it. A friend function can be prototyped using private or public
access specifier.

8.4 Implementing a friend function


First step in implementing a friend function is to prototype the friend function. The friend function is
prototyped inside the class definition. Friend keyword is written in front of the prototype statement
to specify that the function is simply a friend of the class.

Second step is to define the friend function. Definition of the friend function does not include the
use of the friend keyword. It is defined like any other normal function with one exception. An object
is passed as argument to the friend function. Using that object, it then accesses the private members
of the class it is friend of.

Program 1
To implement the concept of friend function
//header files
# include < iostream.h >
# include < conio.h >
//definition of class
class add
{
private:
int var1 ;
int var2 ;
//prototype of friend function
friend void plus ( add ) ;
public:
// default constructor function
add ( )
{
var1 = 0 ;
var2 = 0 ;
}
// parameterized constructor function
add ( int a , int b )
{
var1 = a ;
var2 = b ;
}

void input ( )
{
cout<<" \n Enter value for data member var1 :- " ;
cin>>var1 ;
cout<<" \n Enter value for data member var2 :- " ;
cin>>var2 ;
}

void display ( )
{
cout<<" \n Value of data member var1 :- " << var1 ;
cout<<" \n Value of data member var2 :- " << var2 ;
cout<<" \n Sum of two data members is :- " << var1 + var2 ;
}
};

void main( )
{
// object of class add ;
add obj1, obj2 ( 12, 18 ) ;
//call to member function of obj1
cout<<" \n Object 1 " ;
obj1.input( );
//call to friend function
plus ( obj2 ) ;
// call to member function of obj1
cout<<" \n Object 1 " ;
obj1.display( ) ;
getch();
}

//definition of friend function


void plus ( add obj2 )
{
obj2.var1 = obj2.var1 + 5 ;
obj2.var2 = obj2.var2 + 5 ;
// call to member function of obj2
cout<<" \nObject 2 " ;
obj2.display( );
return ;
}

Following statement is used in the last program to create two objects of the class add:

add obj1, obj2 ( 12, 18 ) ;

For obj1, default constructor will be called as no arguments are passed with. Both the data members
of obj1 are initialized with value 0. For obj2, parameterized constructor will be called as two
arguments are passed with it. the two data members of obj2, i.e. var1 and var2 are set to 12 and 18
respectively.

Friend function is called only once and obj2 is passed as argument to it. The values for its data
members is 12 and 18. In the definition of the friend function, values for both the data members is
incremented by 5. When you display the value of data members of obj2, 17 and 23 will be displayed.
The output for the data members of obj1 will depend on the input given by the user for them.

Output:

Object 1
Enter value for data member var1 :- 30
Enter value for data member var2 :- 40
Object 2
Value of data member var1 :- 17
Value of data member var2 :- 23
Sum of two data members is :- 40
Object 1
Value of data member var1 :- 30
Value of data member var2 :- 40
Sum of two data members is :- 70

Now you have seen the implementation of friend function and also seen the basic features of a
friend function. A friend function of a class can be any function which is not the member function
of that class. Does it mean that a member function of one class can be a friend function of other
class? The answer is , yes. You can successfully make a member function of one class friend of
another class and directly access the private members of the second class.

Program 2
Making a member function of one class friend function of another class
// header files

# include< conio.h >

# include < iostream.h >

// prototype of class rectangle

class rectangle;

//definition of class AREA

class AREA

private:

int area ;

public:

AREA ( ) ;

void compute ( rectangle r2 ) ;

void display ( ) ;

};

// definition of class rectangle

class rectangle

private:
int length ;

int breadth ;

public:

//friend function

friend void AREA::compute ( rectangle ) ;

//constructor functions

rectangle ( )

length = 0 ;

breadth = 0 ;

rectangle ( int a , int b )

length = a ;

length = b ;

void input ( )

cout<<" \n Enter the length of the rectangle :- " ;

cin>>length ;

cout<<" \n Enter the breadth of the rectangle :- " ;

cin>>breadth ;

};

AREA::AREA ( )

area = 0 ;

void AREA::compute ( rectangle r2 )

{
area = r2.length * r2. breadth;

void AREA::display ( )

cout<<" \n Area of rectangle is :- " << area ;

void main ()

// object of AREA class

AREA a1;

//object of class rectangle

rectangle r1;

//accessing the member function of class rectangle

r1.input ( ) ;

//call to friend member function

a1.compute ( r1 ) ;

//call to member function of class rectangle

a1.display ( );

getch();

The last program starts with the prototype of rectangle class. It is so because the compute member
function of the class AREA is passes object of the class rectangle as argument. The member functions
of the class AREA are defined after the definition of class rectangle because the compute member
function of class AREA accesses the private members of class rectangle.

Output:

Enter the length of the rectangle :- 12

Enter the breadth of the rectangle :- 10

Area of rectangle is :- 120

You can also make a function friend of two classes. In the next program you will see how to make
a function friend function of two classes.
Program 3
Making a function friend function of two classes
// header files

# include< conio.h >

# include < iostream.h >

// prototype of class square

class square ;

// definition of class rectangle

class rectangle

private:

int length ;

int breadth ;

// friend function

friend void area ( square, rectangle );

public:

//constructor functions

rectangle ( )

length = 0 ;

breadth = 0 ;

rectangle ( int a , int b )

length = a ;

length = b ;

};

class square
{

private:

int length ;

// friend function

friend void area ( square, rectangle );

public:

//constructor functions

square ( )

length = 0 ;

square ( int a )

length = a ;

};

void main ()

// object of square class

square s1 ;

//object of rectangle class

rectangle r1;

//call to friend function

area (s1, r1 );

getch ( ) ;

voidarea ( square s2 , rectangle r2 )

int areas ;
int arear ;

cout<<" \n Enter the length of the rectangle :- " ;

cin>>r2.length ;

cout<<" \n Enter the breadth of the rectangle :- " ;

cin>>r2.breadth ;

arear = r2.length * r2.breadth ;

cout<<" \n Area of rectangle is :- " << arear ;

cout<<" \n Enter the length of the square:- " ;

cin>>s2.length ;

areas = s2.length * s2.length ;

cout<<" \n Area of square is :- " << areas ;

Output:

Enter the length of the rectangle :- 12

Enter the breadth of the rectangle :- 10

Area of rectangle is :- 120

Enter the length of the square :- 10

Area of square is :- 100

8.5 Friend class


So far you have learned about a friend function andhow to make a function friend of two classes. In
this section you will learn to create a friend class. Making a member function friend of some class,
you can only access the private members of one class with the definition of the friend member
function of another class. But using the concept of friend class, you can make the entire class friend of
another class and access private members of first class from anywhere within the definition of second
class.

8.6 Creating a friend class


Following is the program to make a class friend of another class:
Program 4
Making a class friend of another class
// header files
# include< conio.h >

# include < iostream.h >

// definition of class rectangle

class rectangle

private:

// making a friend class

friend class AREA ;

int length ;

int breadth ;

public:

//constructor functions

rectangle ( )

length = 0 ;

breadth = 0 ;

rectangle ( int a , int b )

length = a ;

length = b ;

};

//definition of class AREA

class AREA

private:

int area ;

rectangle r1 ;

public:

AREA ( ) ;
void input ( ) ;

void compute () ;

void display ( ) ;

};

voidAREA::input ( )

cout<<" \n Enter the length of the rectangle :- " ;

cin>>r1.length ;

cout<<" \n Enter the breadth of the rectangle :- " ;

cin>>r1.breadth ;

AREA::AREA ( )

area = 0 ;

void AREA::compute ()

area = r1.length * r1. breadth;

void AREA::display ( )

cout<<" \n Area of rectangle is :- " << area ;

void main ()

// object of AREA class

AREA a1;

//accessing the member functions of friend class AREA

a1.input ( ) ;

a1.compute ( ) ;

a1.display ( );
getch();

Output:

Enter the length of the rectangle :- 12

Enter the breadth of the rectangle :- 12

Area of rectangle is :- 144

11.2 Inheritance

Inheritance is the most powerful feature of the object oriented programming. Inheritance lets you
create a new class by directly acquiring the attributes and behavior of other already existing
classes and then extending or adding features to those classes. The existing class is called base
class and the newly created class is called derived class.

The main advantages of the inheritance are as follows:


:
 Reusability of the already defined code in the base class.
 It increases the reliability of the code as we are inheriting code that is pre-compiled and
already in use.
 C++ also allows you to extend the features of the base class.

11.3 Types of inheritance

C++ supports following types of inheritance:

1. Single Inheritance
A derived class inheriting features of a single base class is called single inheritance.

Figure 11.1 Single inheritance

2. Multilevel Inheritance
When a class is derived from a class, that itself is derived from a base class, this type of inheritance is
called multilevel inheritance.

Figure 11.2 Multilevel inheritance

3. Multiple Inheritance
A derived class inheriting features of more than one base class is called multiple inheritance.
Figure 11.3 Multiple inheritance

4. Hierarchical Inheritance
When the features of one base class are inherited by multiple classes, it is called hierarchical
inheritance.

Figure 11.4 Hierarchical inheritance

5. Hybrid inheritance
Combination of multiple and hierarchical inheritance is called hybrid inheritance.

Figure 11.5 Hybrid inheritance

11.4 Defining a derived class

A derived class is defined using a base list of classes it is derived from. The base list is given at the
end of class header followed by the colon operator. A base list specifies the relationship between the
base and the derived class.

For single inheritance, a derived class may be defined as follows:

Figure 11.6 Defining derived class


Colon operator is used to indicate the fact that the derived class is derived from the base class and
there is a relationship between the two. Visibility-mode is used to specify the type of access control
used to inherit the base class and can either be private or public. By default the visibility-mode is
private.

Let us try a program to implement the concept of single inheritance.

Program 11.1 To implement single level inheritance

#include<iostream.h>
#include<conio.h>

class student
{
private:
int rollno;
char name[20];

public:
void GetData()
{
cout<<"Enter RollNo :- ";
cin>>rollno;
cout<<"Enter Name :- ";
cin>>name;

void DisplayData()
{
cout<<"\nRollNo : "<<rollno;
cout<<"\nName : "<<name;
}
};

class marks : public student


{
private:
float m1,m2,m3;
float total, average;

public:
void GetMarks()
{
cout<<"Enter Marks for subject 1 :- ";
cin>>m1;
cout<<"Enter Marks for subject 2 :- ";
cin>>m2;
cout<<"Enter Marks for subject 2 :- ";
cin>>m3;
}

void Compute()
{
total = m1 + m2 + m3;
average = total/3;
}

void DisplayMarks()
{
cout<<"\nMarks in Subject 1 : "<<m1;
cout<<"\nMarks in Subject 2 : "<<m2;
cout<<"\nMarks in Subject 3 : "<<m3;
cout<<"\nTotal Marks : "<<total;
cout<<"\nAverage marks : "<<average;
}
};

void main()
{
// object declaration
marks obj;

obj.GetData();
obj.GetMarks();
obj.Compute();
obj.DisplayData();
obj.DisplayMarks();

getch();
}

Output:

Enter RollNo :- 1
Enter Name :- aman
Enter Marks for subject 1 :- 67
Enter Marks for subject 2 :- 68
Enter Marks for subject 3 :- 70

RollNo :
Name :
Marks in Subject 1 : 67
Marks in Subject 2 : 68
Marks in Subject 3 : 70
Total Marks : 205
Average marks : 68.33

C++ allows you to inherit only the visible members of the base class. By visible members we
mean the members declared under the public access modifier. The members that are not
visible are also created, but direct access to them from the derived class is not allowed.

In the last program,

class student
{
private:
int rollno;
char name[20];

public:
void GetData();
void DisplayData();
};

Only the two member functions are inherited by the derived class as they are declared using the
public access modifier and the data members can be indirectly accessed using the two member
functions.

Is it possible to inherit the private members of the base class?


11.5 Protected access modifier

C++ does not directly allow you to access them, but provides another access modifier called
protected that is a modified private access modifier.

Just like private members, protected members of a class are also not accessible outside the
class except from the classes that derive that class. It means private members declared using the
protected access modifier can be inherited by the derived class and rest of its properties are same as
that of private members.

C++ provides a total of three member access control modifiers

1. Private: It does not allow members declared using private access control modifier to be accessed
outside the class.

2. Public: It allows members declared using public access control modifier to be accessed outside the
class.

3. Protected: It is a modified private control access modifier and only useful in case of inheritance. It
allows access to the members declared using protected access control modifier from inside the same
class and the classes that derive this class. Protected members are not accessible outside these two
classes.

For example,
class student
{
private:
int rollno;

protected:
char name[20];

public:
void GetData();
void DisplayData();
};

class marks
{

void display()
{
Cout<<rollno; // not allowed, private member not inheritable , error

Cout<<name; // allowed, protected member are inheritable


}

};

Also the protected moodier can also be used as visibility-mode when defining the header of the
derived class, i.e. protected inheritance of the members of the base class is possible.

Types of class derivations

C++ allows you to inherit the base class using three derivations called private, public and protected.
Class derivations are also called the visibility-modes. What is the difference between the private,
protected and public modes of inheritance? Now that we have three types of access modifiers and
3 types of visibility modes to inherit the base class, let us compare the 3 visibility modes as to how
they inherit the members of the base class.

Table 11.1 Class derivations

Private members are not inheritable. Private visibility mode of inheritance results in the base class
protected and public members to become the private member of the derived class. Protected visibility
mode of inheritance results in the base class protected and public members to become the protected
member of the derived class. Public visibility mode of inheritance does not result in any change to the
access modifier of the base class protected and public members. The base class public members
become the public members of the derived class and base class protected members become the
protected members of the derived class.

11.6 Overriding of base class members

Overriding of base class members is an important concept of inheritance. By overriding member of


base class we mean to have a data member or member function of the same name in the derived
class. It is perfectly allowed in C++, but special care needs to be taken off when implementing the
same.

Let us consider the following piece of code:

Class base
{
Private:
// data members

Public:
//member functions

void input()
{
//function body
}
};

Class derived : public base


{

private:
// data members

public:
//member functions

void input()
{
//function body
}
};

In the last example, both the base and the derived class have a function with the same name. It is
different from function overloading.

Function overloading is achieved by having two functions with the same name but having either
different number of arguments or different type of arguments. Function overriding lets you create two
functions with the same name and same signature, i.e. same number of arguments and same type of
arguments.

What happens when we call the function which has been overridden? Let us consider the following
example,

Program 11.2 To demonstrate the concept of function overriding


#include<conio.h>
#include<iostream.h>

class base
{
private:
int ba;

public:
void input()
{
cout<<”Base class input function”;
}
};

class derived : public base


{
private:
int da;

public:
void input()
{
cout<<”Derived class input function”;
}
};

void main()
{
// derived class object
derived obj;

// call to overridden function


obj.input();

getch();
}

Output:

Derived class input function

When we place call to the base class function that has been overridden by the derived class,
the derived class function gets executed.
But it is possible to execute the base class function which is overridden. The same can be
achieved using the scope resolution operator as follows:

Figure 11.7 Explicitly calling member function of base class

Program 11.3 Explicit call to overridden member function of the base class

#include<conio.h>
#include<iostream.h>

class base
{
private:
int ba;

public:
void input()
{
cout<<”\nBase class input function”;
}
};

class derived : public base


{
private:
int da;

public:
void input()
{
cout<<”\nDerived class input function”;
}
};

void main()
{
// derived class object
derived obj;

// call to overridden function


obj.input();

// call to base class function using scope resolution operator


obj.base::input();

getch();
}

Output:
Derived class input function
Base class input function

11.7 Nesting of member functions

So far we have seen that a member function of a class can be called only by using an object of that
class with a dot operator. However, there is another indirect method of calling a member function of
the class. A member function of a class can be called by writing a function call statement to the same
function in the definition of any other member function of the same class. This concept is called
nesting of member functions.

We can effectively use nesting of member functions to execute member functions that have
been overridden. We can execute all instances of the same function using a single function
call statement from outside the class.

Program 11.4 To implement nesting of overridden base class function

#include<conio.h>
#include<iostream.h>

class base
{
private:
int ba;

public:
void input()
{
cout<<”\nBase class input function”;
}
};

class derived : public base


{
private:
int da;

public:
void input()
{

// call to base class function using scope resolution operator


// nested function call statement
base::input();

cout<<”\nDerived class input function”;


}
};

void main()
{
// derived class object
derived obj;

// call to overridden function


obj.input();

getch();
}
Output:

Base class input function


Derived class input function

The nesting of member functions can be used when the programmer doesn’t wish to give
direct access to a member function from outside the class, or in other words want to control
the visibility of member function.

Program 11.5 Nesting of private member function of the class

#include<conio.h>
#include<iostream.h>

class base
{
protected:
int ba;

};

class derived : public base


{
private:
int da;

void compute()
{
cout<<”\nResult of ba divided by da is :- “<<ba/da;
}

public:
void input()
{
cout<<”Enter value of ba :- “;
cin>>ba;

cout<<”Enter value of da :- “;
cin>>da;
}

void display()
{
if ( da != 0 )
{
// call to member function
compute();
}
else
{
cout<<”\nValue of da is invalid”;
}
}

};

void main()
{
// derived class object
derived obj;

obj.input();
obj.display();

getch();
}

Output:

If you enter non-zero value for da

Enter value of ba :- 12
Enter value of da :- 4
Result of ba divided by da is :- 3

If you enter zero value for da (call to function compute() is not made)

Enter value of ba :- 12
Enter value of da :- 0
Value of da is invalid

11.8 Constructors and inheritance

Constructor is a member function of a class that is automatically called when the object of the same
class is created. In case of inheritance, it is different. When we create the object of the derived class,
constructor the base class is automatically executed and there is no need to create the object of the
base class in order to execute its constructor. Let us try a program and see the ordering in which the
constructor function is called when an object of the derived class is created:

Program 11.6 To check the order of execution of constructor function in case of inheritance

#include<conio.h>
#include<iostream.h>

class base
{
private:
int ba;

public:
//constructor definition
base()
{
cout<<”\nBase class constructor”;
}
};

class derived : public base


{
private:
int da;

public:
//constructor definition
derived()
{
cout<<”\nDerived class constructor”;
}
};

void main()
{
// derived class object
derived obj;

getch();
}

Output:

Base class constructor


Derived class constructor

The base class constructor is executed first and then the constructor of the derived class. We can
also explicitly place a call to the base class constructor using the base class name and the scope
resolution operator.

11.9 Destructors and inheritance

Destructor is a function that is automatically called when the object of that class is destroyed. Again in
case of inheritance, it is different. When the object of the derived class is destroyed, the destructor
function of the base class is automatically executed. Let us try a program and see the ordering in
which the destructor function is executed when object of the derived class is destroyed:

Program 11.7 To check the order of execution of destructor function in case of inheritance
#include<conio.h>
#include<iostream.h>

class base
{
private:
int ba;

public:
//constructor definition
base()
{
cout<<”\nBase class constructor”;
}

//destructor definition
~base()
{
cout<<”\nBase class destructor”;
}

};

class derived : public base


{
private:
int da;

public:
//constructor definition
derived()
{
cout<<”\nDerived class constructor”;
}

//destructor definition
~derived()
{
cout<<”\nDerived class destructor”;
}

};

void main()
{
// derived class object
derived obj;

getch();
}

Output:

Base class constructor


Derived class constructor

Derived class destructor


Base class destructor

Order of execution of destructors in case of inheritance is opposite the order of execution of


constructors. The destructor of the derived class is executed first and then destructor of the
base class.

12.2 Argument passing to the constructor of the base class

The main objective of creating constructor function in any class is to initialize it data members. C++
also allows you to pass initialization value to the constructor function and such constructors are called
parameterized constructors. In this section we will see how to pass arguments to the constructor of
the derived class, which in turn pass argument to the base class constructor.

The derived class constructor is passed all the initialization values required by all classes and it is the
responsibility of the derived class to pass initialization values to the base class constructor. The
derived class constructor receives the entire list of arguments and passes the arguments meant for
the base class constructor in the order of their declaration.

The header of the derived class constructor is divided into two parts divided by colon operator. The
first part consists of declarations of all arguments passed to the derived class constructor and part
includes function calls to the base constructors.

For example,

derived (int a, int b) : base(a)

The last statement is a function header of the derived class. Total of two arguments is passed to the
derived class constructor and the first part of the function header includes the declaration statement of
two formal arguments and the second part contains function call statement to the base class
constructor.
Let us try a program to implement the concept:

Program 12.1 Argument passing to base class constructor using object of derived class
#include<iostream.h>
#include<conio.h>

class base
{
private:
int ba;

public:
//constructor definition without arguments
base()
{
cout<<”\nBase class constructor without arguments”;
ba= 0;
cout<<”\nValue of ba initialized to :- ”<<ba;
}

//parameterized constructor definition


base( int b1)
{
cout<<”\nBase class constructor with arguments”;
ba= b1;
cout<<”\nValue of ba initialized to :- ”<<ba;
}
};

class derived : public base


{
private:
int da;

public:
//constructor definition without arguments
derived()
{
cout<<”\nDerived class constructor without arguments”;
da= 0;
cout<<”\nValue of da initialized to :- ”<<da;
}

//parameterized constructor definition


derived( int b1, int d1) : base(b1)
{
cout<<”\nDerived class constructor with arguments”;
da= d1;
cout<<”\nValue of da initialized to :- ”<<da;
}
};

void main()
{
// derived class object without arguments
cout<<”\nSimple object created”;
derived obj1;

// derived class object with arguments


cout<<”\n\nObject with arguments created”;
derived obj2(100, 200);
getch();
}

Output:

Simple object created


Base class constructor without arguments
Value of ba initialized to :- 0
Derived class constructor without arguments
Value of da initialized to :- 0

Object with arguments created


Base class constructor with arguments
Value of ba initialized to :- 100
Derived class constructor with arguments
Value of da initialized to :- 200

12.3 Multilevel inheritance

It is not unusual that a class is derived from another derived class. The class that is derived from a
base class and is further used to derive another class is called intermediate base class.

An intermediate class using multilevel inheritance may be declared as follows:

class A
{
};

class B : public A
{
};

class C : public B
{
};

In the last example class A serves as a base class to class B which further serves as base to class C.
Class B acts both as derived class to class A and base to class C, hence the class B may be
considered as an intermediate base class.

Program 12.2 Implementing multilevel inheritance

#include<iostream.h>
#include<conio.h>

//base class definition


class top
{
public :
int var1;
void GetData()
{
cout<<"\n\nEnter any Number : ";
cin>>var1;
}
void PutData()
{
cout<<"\nNumber you entered is : "<<var1;
}
};
//intermediate base class and first level inheritance
class middle :public top
{
public:
int var2;
void Square()
{
// call to member function of base class
GetData();

var2 = var1*var1;
cout<<"\nSquare is : "<<var2;
}
};

//Second level inheritance


class bottom :public middle
{
public:
int var3;
void Cube()
{
// call to member function of intermediate base class
Square();
var3=var2*var1;
cout<<"\nCube is : "<<var3;
}
};

int main()
{
bottom obj;

//call to member function


obj1Cube();
getch();
}

Output:

Enter any Number : 5


Number you entered is : 5

Square is : 25
Cube is : 125

12.4 Multiple inheritance

It is possible to inherit derive class from two or more base classes. This type of inheritance is called
multiple inheritance. The level of inheritance is single only. Multiple inheritance allows a class to
derive features of more than one class, combine them and construct a new class.

Multiple inheritance may be declared as follows:

class A
{
};
class B
{
};

class C : public A, public B


{
};

Program 12.3 Implementation of multiple inheritance

#include<iostream.h>
#include<conio.h>

class Student
{
protected:
int rollno;
char name[25];
public:
void GetData()
{
cout<<”Enter roll number :- “;
cin>>rollno;

cout<<”Enter name :- “;
cin>>name;
}

void PutData()
{
cout<<"\nRoll number :- "<<rollno;
cout<<"\nName :- "<<name;
}
};

class Test
{
protected:
float subj1,subj2;
public:
void GetMarks()
{
cout<<”Enter Marks in first subject :- “;
cin>>subj1;

cout<<”Enter Marks in second subject :- “;


cin>>subj2;
}
void PutMarks()
{
cout<<"\nMarks in first subject :- "<<subj1;
cout<<"\nMarks in second subject :- "<<subj2;
}
};
class Result : public Student, public Test
{
private:
float total;
public:
void Display()
{
PutData();
PutMarks();
total = subj1 + subj2;
cout<<"\nTotal marks :- "<<total;
}

void Input ()
{
void GetData();
void GetMarks();
}
};

void main()
{
//object declaration
Result obj;

//call to member functions


obj.Input();
obj.Display();

getch();
}

Output:

Enter roll number :- 1


Enter name :- amit
Enter Marks in first subject :- 65
Enter Marks in second subject :- 67

Roll number :- 1
Name :- amit
Marks in first subject :- 65
Marks in second subject :- 67
Total marks :- 130

Ambiguity problem in multiple inheritance

Sometimes there may be a situation when the same member function is defined in more than one
base class used to inherit a derived class in multiple inheritance. Now if the same member function
also appears in the derived class, then it may not be a problem. But if the same member function is
not present in the derived class, call to that member function will result into the ambiguous member
function call.

Consider the following example,

Program 12.4 Demonstrating ambiguity problem in multiple inheritance

#include<iostream.h>
#include<conio.h>

class Base1
{
protected:
int b1;
public:
void GetData()
{
cout<<”Enter value of b1 :- “;
cin>>b1;
}

void PutData()
{
cout<<"\nValue of b1 :- "<<b1;
}
};

class Base2
{
protected:
int b2;
public:
void GetData()
{
cout<<”Enter value of b2 :- “;
cin>>b2;
}

void PutData()
{
cout<<"\nValue of b2 :- "<<b2;
}
};

class Derived : public Base1, public Base2


{
private:
int d1;
public:
void read()
{
cout<<”Enter value of d1 :- “;
cin>>d1;
}

void write()
{
cout<<"\nValue of d1 :- "<<d1;
}

void main()
{
//object declaration
Derived obj;

//call to member functions


obj.read();
obj.write();
obj.GetData(); //error
obj.PutData(); //error
getch();
}

Now the member functions Getdata() and PutData() are defined in both the base classes, when a
function call statement is made to these functions, the compiler fails to bind the requested function
with the function call statement. This situation is called ambiguous member function call
statement.

To overcome this problem, you must specify the class name using the scope resolution operator to
specify the class whose member function needs to be executed.

For example,

obj.base1::GetData();

The last statement specifies to the compiler that GetData() of base1 should be executed.

12.5 Hierarchical inheritance

When there is a situation where multiple classes are derived from a single base class, this type of
inheritance is called hierarchical inheritance. The level of inheritance is single only and all derived
classes directly inherit the base class.

Hierarchical inheritance may be declared as follows:

class A
{
};

class B : public A
{
};

class C : public A
{
};

There are no real issues with the implementation of the hierarchical inheritance. As there is
only a single base class and all derived class can access members of the base class using
their own objects.

Program 12.5 To implement hierarchical inheritance

#include<iostream.h>
#include<conio.h>

//Base Class definition


class base
{
protected:
int num, result;
public:
void getnumber()
{
cout<<"\n\nEnter any number :- ";
cin>>num;
}
};

//derived Class definition


class derived1 : public base
{
public:
void square()
{
result = num * num;
cout<<"\n\nSquare of the number :- “<<result;
}
};

//derived Class definition


class derived2 :public base
{
public:
void cube()
{
result = num * num * num;
cout<<"\n\nCube of the number :- “<<result;
}
};

int main()
{

// object of derived1 class


derived1 d1;

// object of derived2 class


derived2 d2;

d1.getnumber();
d1.square();

d2.getnumber();
d2.cube();

getch();
}

Output:

Enter any number :- 12


Square of the number :- 144

Enter any number :- 10


Cube of the number :- 1000

12.6 Hybrid inheritance

There may be a situation when you wish to combine two or more types of inheritance to design a new
class. This type of inheritance is called hybrid inheritance.

For example,
Figure 12.1 Hybrid inheritance

It is combination of multilevel and hierarchical inheritance. Implementing hybrid inheritance is


similar to implementing any other inheritance, but there are situations where you might get caught into
trouble.

The diamond or grandparent problem

The diamond problem occurs when two base classes of a derived class are further derived from a
common base class. This type of inheritance is a combination of hierarchical inheritance at first level
and multiple inheritance at the second level of inheritance. Look at the following figure.

Figure 12.2 Diamond shape hybrid inheritance

Creating object of class TA will result in inheriting the members of the class Person twice, one through
the Faculty class and one through the Student class. But we only need to inherit single instance of
members of class Person. This objective can be achieved by inheriting the class Person as virtual
base class. Only single instance of the members of virtual base class is inherited.

class Person
{
protected:
int age;
char name;

};

class Faculty : virtual public Person


{ ..
...
};

class Student : virtual public Person


{ ..
...
};

class TA : public Faculty, public Student


{ ..
..
};

12.7 Types of Base Classes

Any class you create in C++ can serve as a base class. A class derived from the base class may also
be defined as a base of another class. On the basis of level of inheritance, a base can be categorized
into following two categories.

12.7.1 Direct Base Classes

A class is considered to be direct base class of a derived class if it is mentioned in the base list of the
derived class. Consider the following definition of the derived class:

Figure 12.3 Example of direct base class

12.7.2 Indirect base classes

A derived class can itself serve as a base class for another derived class. When a derived class is
included in the base list of another derived class, the last derived class inherits the properties of both
the base classes, i.e. the derived class (D1) directly inherited by it and the base class inherited by the
derived class (D1).

In simple words, we can say that, when a super base class is inherited from an intermediate base
class which is further inherited by a derived class, the super base class is considered to be an indirect
base class of second level derived class.

Consider the following definition of the derived class:


Figure 12.4 Example of in-direct base class

You might also like