Constructors and Destructors STATIC ANF FRIEND FINAL
Constructors and Destructors STATIC ANF FRIEND FINAL
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();
}
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.
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();
}
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
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();
}
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;
}
//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( )
{
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.
}
};
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>
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
//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 ;
}
};
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();
}
Following statement is used in the last program to create two objects of the class add:
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
class rectangle;
class AREA
private:
int area ;
public:
AREA ( ) ;
void display ( ) ;
};
class rectangle
private:
int length ;
int breadth ;
public:
//friend function
//constructor functions
rectangle ( )
length = 0 ;
breadth = 0 ;
length = a ;
length = b ;
void input ( )
cin>>length ;
cin>>breadth ;
};
AREA::AREA ( )
area = 0 ;
{
area = r2.length * r2. breadth;
void AREA::display ( )
void main ()
AREA a1;
rectangle r1;
r1.input ( ) ;
a1.compute ( r1 ) ;
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:
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
class square ;
class rectangle
private:
int length ;
int breadth ;
// friend function
public:
//constructor functions
rectangle ( )
length = 0 ;
breadth = 0 ;
length = a ;
length = b ;
};
class square
{
private:
int length ;
// friend function
public:
//constructor functions
square ( )
length = 0 ;
square ( int a )
length = a ;
};
void main ()
square s1 ;
rectangle r1;
area (s1, r1 );
getch ( ) ;
int areas ;
int arear ;
cin>>r2.length ;
cin>>r2.breadth ;
cin>>s2.length ;
Output:
class rectangle
private:
int length ;
int breadth ;
public:
//constructor functions
rectangle ( )
length = 0 ;
breadth = 0 ;
length = a ;
length = b ;
};
class AREA
private:
int area ;
rectangle r1 ;
public:
AREA ( ) ;
void input ( ) ;
void compute () ;
void display ( ) ;
};
voidAREA::input ( )
cin>>r1.length ;
cin>>r1.breadth ;
AREA::AREA ( )
area = 0 ;
void AREA::compute ()
void AREA::display ( )
void main ()
AREA a1;
a1.input ( ) ;
a1.compute ( ) ;
a1.display ( );
getch();
Output:
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.
1. Single Inheritance
A derived class inheriting features of a single base class is called 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.
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.
5. Hybrid inheritance
Combination of multiple and hierarchical inheritance is called hybrid inheritance.
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.
#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;
}
};
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.
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.
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.
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
};
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.
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.
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.
Class base
{
Private:
// data members
Public:
//member functions
void input()
{
//function body
}
};
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,
class base
{
private:
int ba;
public:
void input()
{
cout<<”Base class input function”;
}
};
public:
void input()
{
cout<<”Derived class input function”;
}
};
void main()
{
// derived class object
derived obj;
getch();
}
Output:
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:
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”;
}
};
public:
void input()
{
cout<<”\nDerived class input function”;
}
};
void main()
{
// derived class object
derived obj;
getch();
}
Output:
Derived class input function
Base class input function
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.
#include<conio.h>
#include<iostream.h>
class base
{
private:
int ba;
public:
void input()
{
cout<<”\nBase class input function”;
}
};
public:
void input()
{
void main()
{
// derived class object
derived obj;
getch();
}
Output:
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.
#include<conio.h>
#include<iostream.h>
class base
{
protected:
int ba;
};
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:
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
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”;
}
};
public:
//constructor definition
derived()
{
cout<<”\nDerived class constructor”;
}
};
void main()
{
// derived class object
derived obj;
getch();
}
Output:
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.
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”;
}
};
public:
//constructor definition
derived()
{
cout<<”\nDerived class constructor”;
}
//destructor definition
~derived()
{
cout<<”\nDerived class destructor”;
}
};
void main()
{
// derived class object
derived obj;
getch();
}
Output:
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,
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;
}
public:
//constructor definition without arguments
derived()
{
cout<<”\nDerived class constructor without arguments”;
da= 0;
cout<<”\nValue of da initialized to :- ”<<da;
}
void main()
{
// derived class object without arguments
cout<<”\nSimple object created”;
derived obj1;
Output:
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.
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.
#include<iostream.h>
#include<conio.h>
var2 = var1*var1;
cout<<"\nSquare is : "<<var2;
}
};
int main()
{
bottom obj;
Output:
Square is : 25
Cube is : 125
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.
class A
{
};
class B
{
};
#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;
void Input ()
{
void GetData();
void GetMarks();
}
};
void main()
{
//object declaration
Result obj;
getch();
}
Output:
Roll number :- 1
Name :- amit
Marks in first subject :- 65
Marks in second subject :- 67
Total marks :- 130
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.
#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;
}
};
void write()
{
cout<<"\nValue of d1 :- "<<d1;
}
void main()
{
//object declaration
Derived obj;
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.
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.
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.
#include<iostream.h>
#include<conio.h>
int main()
{
d1.getnumber();
d1.square();
d2.getnumber();
d2.cube();
getch();
}
Output:
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
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.
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;
};
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.
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:
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.