C++ (C Plus Plus Programming)
C Plus Plus
Chapter 1 Introduction
c++ is an object-oriented programming language. It was developed by Bjarne Stroustrup at AT&T Bell
Laboratories in early 1980‟s.
Some points:-
1. In c++, header file <iostream.h> is included. This inclusion is must because all standard functions
are stored in it.
2. Complier of c++ is Turbo c++ which also support c.
3. extension of c++ program is .cpp.
Object-Oriented Programing(OOP)
OOP was developed to reduce the inherent limitation of traditional programming language( e.g. c,
BASIC, Pascal ). Large program written in traditional programming language are complex. In OOP‟s the
main emphasis is on data, not on procedure. In OOP‟s, we bundle together the data and the function that
operate on the data to a single software unit called “Class”.
Characteristics of OOP’s Language : -
The main characteristics of OOP Language are followings:_
1. Data Abstraction :- Data abstraction means identifying necessary information and hiding unnecessary
details.
2. Data Encapsulation :- Binding both data and code in to a single entity(Object) is known as Data
Encapsulation. It main purpose is to keep both data and code safe from outside interference and
misuse.
3. Polymorphism :- Polymorphism means “one interface, multiple methods”. It means existing one
thing in many format. In simple terms, Polymorphism is the attribute that allows one interface to
control access to a general class of actions.
This feature is further divided into two parts:-
Operator Overloading
Function Overloading
4. Inheritance :- Inheritance is the process by which one object can acquire the properties of another
code.
Input-Output Operator in c++
Input Operator:- The operator >> is known as extraction or get from operator. It extracts(or takes)
the value from the keyboard and assign it to the variable on its right.
The identifier cin (pronounced as „c - in‟) is a predefined object that represent the standard input stream in
c++. The standard input stream represent keyboard.
Output Operator:- The operator << is known as insertion or put to operator. It inserts(or send) the
value of the variable on its right to the object on its left.
The identifier cout (pronounced as „c -out‟) is a predefined object that represent the standard output stream
in c++. The standard output stream represent monitor.
Return type of main()
In c++, main ( ) returns an integer type value to the operating system. Therefore, every
main ( ) in c++ should end with a return (0) statement ; otherwise an error or warning might
occur. For not returning any value, return type of main( ) is specified as void.
A short program in c++
#include <iostream.h>
#include <conio.h>
void main( )
{
int a ; cout<< ”Enter value of a::” ;
cin>> a ; cout<<”\nValue of a is::”<< a ; getch ( ) ;
}
inline function_header
{
function body
}
Chapter 2 Datatype and Function
Keywords:-
Keywords are reserved words and cannot be used as names of the program variables or other user-
defined program elements. All c‟s keywords are also used in c++. Some extra keywords are also added in
c++ which are following:-
asm operator new catch class delete
friend inline private protected public template
this throw try virtual
Datatype and Operator in c++
Because c++ is a superset of c, so it supports all the feature of c. Datatype and operators in c++ is same
as in c. Some additional operators are:-
:: scope resolution operator
::* Pointer -to member declarator
->* Pointer -to member operator
.* Pointer -to member operator
delete Memory release operator
new Memory allocation operator
endl Line feed operator
setw field width operator
Control Structure in c++:-
All control structures ( if ,if-else, for , while, do-while, case) are same as in c.
Function Functions are same as in c. In c++ a function can return a reference.
Example:
int & max ( int & x, int & y )
{
if ( x > y ) { return x; }
else { return y; }
}
Inline function :-
One of the main objective of using function in a program is to save memory space, which become
appreciable when a function is likely to be called many times. But every time a function is called, it takes a
lot of extra time in executing a series of instructions for tasks such as jumping to the function, saving
registers, pushing arguments into the stack, and returning to the calling function. When function is small, a
substantial percentage of execution time may be spent in such overheads.
To eliminate the cost of calls to small functions, c++ proposes a new feature called inline function. An
inline function is a function that is expanded in line when it is invoked. Inline function execute faster. But
the benefit of inline function reduce as the function grow in size. The inline function is defined as follows:-
inline keyword is used to define a inline function. All inline
function must be defined before they are called.
example:-
inline double cube(double a)
{
return (a * a * a ) ;
}
some situations, where inline function may not work are:-
1. for functions returning values, if a loop, a switch, or a goto exists.
Output of program 2.2
sum of 3 integer value(10,20,30) =
sum = 60
sum of 2 integer value(10,20) =
sum = 30
sum of 2 float value(10.5f,20.3f)=
sum = 30.8
sum of 3 float value (10.5f,20.3f,2.3f)
sum = 33.1
sum of 4 float value (10.5f,20.3f,2.3f,1.1f)=
sum = 34.2
sum of 4 integer value(10,20,2,5) =
sum = 37
Output of program 2.1
a = 100
b = 200
c = 300
sum ( passing a, b, c ) :: 600
sum ( passing a, b ) :: 310
sum ( passing a ) :: 115
2. for functions not returning values, if a return statement exists.
3. If functions contains static variables.
4. if inline functions are recursive.
Default Arguments in function
C++ allows us to call a function without specifying all its
arguments. In such cases, the function assign a default value
to the parameter which does not have a matching argument
in the function call. Default values are specified when the
function is declared. The complier looks at the prototype to
see how many arguments a function uses and alerts the
program for possible default values.
Note:- One important point is that only the trailing arguments can have default value. We must add default
value from right to left.
Example:- // program 2.1
void main ( )
{
int sum( int a ,int b = 5 , int c = 10 ) ;
int r,a,b,c ; a = 100 , b = 200 , c = 300 ;
cout<< ” \n a ” = <<a << ” \n b ” = << b << ” \nc ” = <<c;
r = sum ( a,b,c ); cout << ” \n sum ( passing a, b, c ) :: ” << r;
r = sum( a , b ); cout << ”\n sum ( passing a, b )::”<< r ;
r = sum ( a ) ; cout << ” \n sum ( passing a ) :: ”<< r; getch ( );
}
int sum(int a , int b, int c)
{ return ( a + b + c );
}
Advantage of providing the default arguments are:-
1. We can use default argument to add new parameter to the existing functions.
2. Default arguments can be used to combine similar functions into one.
Function Overloading
Function overloading is a form of Polymorphism that is an important feature of Object Oriented
Programming Languages.
Function Overloading means defining multiple functions with same name having different parameter list. An
overloaded function perform different activities
depending upon on the kind of data sent to it.
Example:-
// program 2.2
#include<iostream.h>
#include<conio.h>
void total( int a, int b);
void total(int a, int b, int c);
void total(float a, float b, float c, float d);
void total(float a, float b, float c);
void total(float a, float b);
void main( )
{
clrscr( );
cout<<"\n sum of 3 integer value(10,20,30) =" ;
total(10,20,30) ;
cout<<"\n sum of 2 integer value(10,20) =" ;
total(10,20) ;
cout<<"\n\n sum of 2 float value(10.5f,20.3f) =" ;
total( 10.5f,20.3f ) ;
cout<<"\n\n sum of 3 float value (10.5f,20.3f,2.3f)=" ;
total(10.5f,20.3f,2.3f) ;
cout<<"\n\n sum of 4 float value (10.5f,20.3f,2.3f,1.1f)=" ;
total(10.5f,20.3f,2.3f,1.1f) ;
cout<<"\n\n sum of 4 integer value(10,20,2,5) =" ;
total(10,20,2,5) ;
getch( ) ;
}
void total( int a, int b)
{
cout<< "\n\t\t sum = " << a + b ;
}
void total( int a, int b, int c)
{
cout<<" \n\t\t sum = " << a + b + c ;
}
void total( float a , float b, float c )
{
cout<<"\n\t\t sum = "<< a + b + c ;
}
void total(float a, float b, float c, float d)
{
cout<<" \n\t\t sum = "<< a + b + c + d;
}
void total(float a, float b)
{
cout<<"\n\t\t sum = "<<a+b;
}
Working of Function Overloading:
The function selection involves the following steps:
1. The compiler first tries to find an exact match in which the type of action are same, and use that
function.
2. If an exact match is not found, the compiler uses the integral promotions to the arguments, such as
char to int float to double
to find a match.
3. When either of them fails, the compiler tries to use the built-in conversions (the implicit assignment
conversions) to the actual arguments and then uses the function whose match is unique. If the
conversion is possible to have multiple matches, then the compiler will generate an error message.
Return-type class-name :: function-name (argument declaration )
{
function body
}
Class class_name
{
private:
variable declaration;
function declaration;
public:
variable declaration;
function declaration;
};
Chapter 3 Classes and Objects
Class: class works like template from which show about the properties and functionality of it‟s objects.
Object: Objects are an instance of a class. They have all the properties and method which are declared in a
class.
A class is a way to bind data and its associated functions together. It allows the data and function to be
hidden, if necessary, from external use. When defining a class, we are created a new abstracted data type
that can be treated like any other built-in data type.
Generally, a class specification has two part:
1. Class declaration
2. Class function defination
The class declaration describes the type and scope of its members. The class function definations
describe how the class functions are implemented.
General form of a class declaration
The functions and variables are collectively called class members.
The keyword public and private are known as visibility labels. The class members that have been
declared as private can be accessed only from within the class, While public members can be accessed from
outside the class also. By default, the members of a class are private.
The variables declared inside the class are known as data members and the functions are known as
member functions. Only the member functions can have access to the private data member and private
member functions. However, the public members(both function and data) can be accessed from outside the
class. This binding of data and functions together into a single class-type variable is referred to as
encapsulation.
Simple Class Example:-
class item
{
int i;
public:
void get ( int a ) ; void put ( void);
};
Creating object:- Objects of any class can be created like as: -
Syntax:- class_name object 1 , object 2 ;
Accessing class member:-
Syntax:- Object-name . function-name ( actual argument ) ;
DEFINING MEMBER FUNCTION:-
Member functions can be defined in two places:-
1. Outside the class defination
Member functions that are declared inside a class have to be defined separately outside the class. The
general form of a member function defination is:-
The membership label class-name :: tells the complier that the function function-name belongs to the
class class-name .That is, the scope of function is restricted to the class-name. The symbol :: is called Scope
Resolution Operator.
The member function have some special characteristics that are ofren used in the program development.
These characteristics are:-
Several different classes can use the same function name. The „membership label‟ will resolve their
scope.
Member function can access the private data of the class. A non-member function cannot do
so.(Exception is Friend function)
A member function can call another member function directly, without using the dot operator.
2. Inside the class definition
Another method of defining a member function is to replace the function declaration by the function
definition inside the class.
Program to demonstrate the class :-
//program 3.1
#include<iostream.h>
class item
{
int num; float cost;
public:
void getdata ( int a , float b ) ;//Prototype declaration to be defined
//function defined inside the class
void putdata ( void )
{
cout << ”\n number::”<< num<< ”\n cost::”<< num;
}
};
//member function definition outside the class
void item:: getdata (int a ,float b)
{
num = a; cost = b;
}
//main function
void main( )
{
item x; //create object
clrscr ( ) ;
cout << ”object x \n“ ;
x.getdata ( 100 , 230.50 ) ;
x..putdata ( ) ;
item y ; //create object
cout <<”object y \n“;
y.getdata( 100 , 230.50) ;
y..putdata ( ) ; getch ( ) ;
}
PRIVATE MEMBER FUNCTION:-
Although it is normal practice to place all the data items in a private section and all the functions in
public, some situation may require certain functions to be hidden from the outside calls. These functions are
declared in private section. A private member function can only be called be another function that is a
member of the class . Even an object cannot invoke a private function using the dot operator.
Example:-
class sample
{
int m;
void read ( ); //private member function
public:
void update ( ); void write( );
};
if s1 is a object of class sample, then
s1.read ( ) ; //won‟t work. object cannot access the private members.
is illegal. However, the function read( ) can be called by the function update( ) to updated the value of m.
void sample ::update( )
{
read ( ) ; //no object used, simple call.
}
MAKING AN OUTSIDE FUNCTION INLINE:-
The member function defined inside the class behaves like inline functions.To make a outside function
inline, inline keyword is used in the header line of function defination.
Example:-
class item
{
int num ; float cost ;
public:
void getdata ( int a, float b) ; //Prototype declaration
};
//member function definition outside the class
inline void item :: getdata (int a , float b)
{
num = a ; cost = b;
}
ARRAY WITHIN A CLASS:-
The arrays canbe used as member variables in a class.
Example:-
//program 3.2
const int size = 3;
class item
{
int a [size];
public:
void getdata ( ); //Prototype declaration to be defined
void putdata ( );
};
//member function definition outside the class
void item:: getdata ( )
{ int j; cout << ”\n enter value : ” ;
for ( j = 0 ; j < size ; j++)
cin >> a [ j ] ;
}
void item :: putdata ( )
{
int j ;
cout << ”\n values are:” ;
for( j = 0 ; j < size ; j++)
cout << endl << a [j] ;
}
//main function
void main ( )
{
item x; //create object
clrscr ( );
cout <<”object x \n“;
x.getdata ( ) ;
x..putdata ( ) ; getch ( );
}
STATIC DATA MEMBER:-
A data member of a class can be qualified as static. A static member variable has certain special
characterstics. These are:
It is intialized to zero when the first object of its class is created. No other intialization is permitted.
Only one copy of that member is created for the entire class and is shared by all the objects of that
class, no matter how many objects are created.
It is visible only within the class, but its lifetime is the entire program.
Static varibles are normally used to maintain values common to the entire class.
STATIC MEMBER FUNCTION:-
A member function can be declared as static member function. A member function that is declared
static has the following properties:
A static function can have access to only other static members( function or varibles ) declared in the
same class.
A static member function can be called using the class name( instead of its objects) as follows:-
class name :: function-name ;
Example:-
// program 3.3
class test
{
int code ; static int count;
public:
void setcode( )
{
code = + + count ;
}
void showcode( )
{
cout << ” \n object number : “ << code ;
}
static void showcount ( )
{ cout << ” \n count : “ << count ;
}
};
int test:: count;
void main( )
{
test t1 , t2 ;
t1.setcode ( ) ;
t2.setcode ( ) ;
test :: showcount ( );
test t3 ;
t3.setcode( ); test :: showcount ( );
Output of program 3.3
count:2
count:3
object number: 1
object number: 2
object number: 3
t1.showcount ( ) ; t2.showcount ( ) ; t3.showcount ( ) ;
getch ( );
}
ARRAY OF OBJECTS:-
We can define array of objects. Since an array of objects behaves like any other array, we can use the
usual array accessing methods to access individual elements, and then the dot member operator to access the
member functions.
Example:-
//program 3.4
class employee
{
char name [20] ;
float age ;
public:
void getdata ( ) ;
void putdata ( ) ;
};
void employee :: getdata ( )
{
cout << ”\nEnter name:” ; cin >> name;
cout << ”\nEnter age:” ; cin >> age;
}
void employee :: putdata ( )
{
cout << ”\nName: “ << name ;
cout << ”\nAge: “ << age ;
}
const int size = 2 ;
void main( )
{
employee e1[size] ;
for(int i = 0 ; i < size ; i++ )
{
cout <<”\n Enter details of employee” << i + 1 << endl ;
e1 [i] . getdata( ) ;
}
for ( i = 0 ; i < size ; i ++ )
{
cout << ”\n Employee”<< i + 1 << endl ;
e1 [i] . putdata ( ) ;
}
getch( ) ;
}
OBJECT AS FUNCTION ARGUMENTS
Like any other data type, an object may be used as a function argument. This can be done in two ways:
A copy of the entire object is passed to the function.
Only the address of the object is transferred to the function.
The first method is called pass-by-value. Since a copy of the object is passed to the functions, any
change made to the object inside te function do not affect the object used to call the function. The second
method is called pass-by-reference. When an address of the object is passed ,the called function works
directly on the actual object used in the call. This means any change made to the object inside te function
will reflect in the actual object.
Output of program 3.4
input
Enter details of employee1
enter name: xxx
enter age: 45
Enter details of employee2
enter name: yyy
enter age: 40
output
Employee 1:
name: xxx
age: 45
Employee 2:
name: yyy
age: 40
class second ;
class first
{ ........ //private member declaration
public:
........ //public member declaration
friend void xyz (first , second) ; //friend function declaration
};
class second
{ ........ //private member declaration
public:
........ //public member declaration
friend void xyz ( first ,second ) ;//friend function declaration
};
void xyz ( first f1 , second s1 ) // friend function defination
{
}
The pass-by-reference method is more efficient since it requires to pass only the address of the object
and not entire object.
Example:-
//program 3.5 //objects are passed call-by-value
class time
{
int hours , min ;
public :
void gettime ( int h , int m )
{ hours = h ; min = m ; }
void puttime( )
{ cout << ”\nHours: “ << hours ;
cout << ”\nMinutes: “ << min ;
}
void sum ( time , time ) ;
};
void time :: sum( time t1,time t2)
{
min = t1.min + t2.min ;
hours = min / 60 ; min = min % 60 ;
hours = hours + t1.hours + t2.hours ;
}
void main()
{
time t1, t2, t3 ;
t1.gettime ( 2, 45) ; t2.gettime( 3, 30) ;
t3.sum ( t1, t2 ) ;
cout << ”\nt1:: “<< t1.puttime( ) ;
cout << ”\nt2:: “<< t2.puttime ( ) ;
cout << ”\nt3:: “ << t3.puttime ( ) ;
getch ( ) ;
}
FRIEND FUNCTION
We know that the private members cannot be accessed from outside the class. It means, a non-member
function cannot have an access to the private data of the class.
But sometimes there are a
situation where we would like
two classes to share a particular
function. In such situation, c++
allows the common function to
be made friendly with both the
classed, thereby allowing th
function to have access to the
private data of these classes.
Such a function need not be a
member of any of these class.
To make an outside function
“friendly” to a class, we have to
simply declare this function a
friend of the class using friend
keyword as shown below:
Output of program 3.5
output
t1: 2 hours and 45 minutes
t2: 3 hours and 30 minutes
t3: 6 hours and 15 minutes
The function that are declared with keyword friend are known as friend function. A function can be declared
as a friend in any number of classes.
A friend function possesses certain special characteristics:
It is not in the scope of the class to which it has been declared as friend.
Since it is not in the scope of the class, it cannot be called using the object of the class.
It can be invoked like a normal function without the help of any object.
Unlike member functions, it cannot access the member names directly and has to use an object
name and dot membership operator with each member name.(e.g. a.x).
It can be declared either in the public or the private part of a class without affecting its meaning.
Usually, it has the objects as arguments.
Example:-
//program 3.6 //objects are passed call-by-value
class abc ; //declaration of class before use or Foreward declaration
class xyz
{ int x ;
public :
void getvalue ( int h )
{ x = h ; }
friend void max ( xyz , abc ) ;
} ;
class abc
{ int a ;
public :
void getvalue ( int j )
{ a = j ; }
friend void max ( xyz , abc ) ; //declaration of friend function
};
void max ( xyz t1, abc t2 ) //defination of friend function
{
if( t1.x >= t2.a )
cout << t1 . x ;
else
cout << t2 . a ;
}
void main( )
{
clrscr ( );
xyz t1 ; abc t2 ;
t1.getvalue (10) ; t2.getvalue(30) ;
cout << ” \n maximum value is::\n”;
max (t1,t2); getch ( ) ;
}
A friend function can be called by reference. In this case, local copies of the objects are not made.
Instead, a pointer to the address of the object is passed and the called function directly works on the actual
objects used in the call.
This method can be used to alter the value of the private members of a class.
Example:-
//program 3.7 for swapping the private data of classes. objects are passed call-by-reference
class abc ; //declaration of class before use or Foreward declaration
class xyz
{
int v1 ;
public :
Output of program 3.6
output
maximum value is::
30
void getvalue ( int h )
{ v1 = h ; }
void display ( )
{ cout << ”\n value of v1 ::” << v1 ; }
friend void swap ( xyz & , abc & ) ;
};
class abc
{ int v2;
public:
void getvalue (int j )
{ v2 = j ; }
void display ( )
{ cout << ”\n value of v2 ::” << v2 ; }
friend void swap ( xyz & ,abc & ) ; //declaration of friend function
};
void swap ( xyz & x,abc & a) //defination of friend function
{
int temp =x.v1 ;
x.v1 = a.v2; a.v2 = temp ;
}
void main( )
{
clrscr( );
xyz t1 ; abc t2 ;
t1.getvalue ( 10 ); t2 . getvalue ( 30 );
t1.display ( ); t2.display ( );
swap( t1 , t2 ) ;
cout << ”\n values after swapping::\n”;
t1.display( ) ; t2.display( ) ; getch( ) ;
}
RETURNING OBJECTS:
A function can not only receive the objects as arguments but also can return them.
Example:-
//program 3.8 for returnin objects.
class time
{
int hours , min ;
public:
void gettime( int h , int m )
{ hours = h ; min = m ; }
void puttime( )
{ cout << ”\nHours: “ << hours ;
cout << ”\nMinutes: “ << min ; }
friend time sum ( time, time ) ;
};
time sum( time t1,time t2)
{
time t3 ;
t3.min = t1.min + t2.min ;
t3.hours = t3.min / 60 ; t3.min = t3.min % 60 ;
t3.hours = t3.hours + t1.hours + t2.hours ;
return t3;
}
Output of program 3.7
output
values after swapping::
value of v1:: 30
value of v2:: 10
Output of program 3.8
output
t1: 2 hours and 45 minutes
t2: 3 hours and 30 minutes
t3: 6 hours and 15 minutes
void main()
{
time t1,t2,t3 ;
t1.gettime (2, 45 ) ; t2.gettime ( 3, 30 ) ;
t3 = sum ( t1, t2 ) ; // t3 = t1 + t2
cout << ”\nt1::” ; t1.puttime( ) ;
cout << ”\nt2::” ; t2.puttime( ) ;
cout << ”\nt3::” ; t3.puttime( ) ; getch ( ) ;
}
FRIEND CLASS:
Using friend function, we can access only data variables of classes. While making friend class, we can
access procedure and data also.
Example:
//program 3.9 friend class
class abc; //declaration of class before use or Forward declaration
class xyz
{ int x ;
public :
void getvalue ( ) ;
// void show ( )
friend class abc ; // all member functions of abc are friend to xyz
};
class abc
{ int a ;
public :
void get( )
{ xyz x1 ; x1.getvalue( ) ; x1.show(); }
} ;
void main( )
{
clrscr( ) ; abc a1 ;
a1.get ( ) ; getch( ) ;
}
In this program, we declare an object of class xyz in the get( ) function of class abc and call the
getvalue( ) function of class xyz.
POINTERS TO MEMBERS:
Example:
//program 3.10 //dereferencing operator
class first
{
int x , y ;
public:
void set( int a, int b)
{ x = a ; y = b ; }
friend int sum ( first ) ;
};
int sum ( first f1 )
{
int first :: * px = & first :: x ;
int first :: * py = & first :: y ;
first *pm = & f1 ;
int s = f1 . *px + pm->*py ; return s ; }
Output of program 3.10
output
sum= 30
sum= 70
void main( )
{
first f1;
void (first :: *pf ) ( int , int ) = & first :: set( ) ;
(f1. *pf ) (10,20) ;
cout << ”\nsum=” << sum( f1 ) ;
first *op = &f1;
(op->*pf)(30 , 40) ;
cout << ”\nsum = ” << sum( f1 ) ; getch( ) ;
}
Chapter 4 - Constructor and Destructor
Constructor is the special member function whose task is to initialize the objects of its class. It has
same name as the class name. The constuctor is invoked whenever an object of its associated class is
created. It is called constructor because it constructs the values of data member of the class.
Constructor functions have some special characterstics. These are:
They should be declared in the public section.
They are invoked automatically when the objects are created.
They donot have return types, not even void and they can not return values.
They cannot be inherited, though a derived class can call the base class constuctor.
Constructors cannot be virtual.
They make a „implicit calls‟ to the operators new and delete when memory allocation is required.
They can have default arguments.
TYPES:
Constructors are of following types:-
1. Default constructor 2. Parametrized constructor
3. Copy constructor 4. Dynamic constructor
DEFAULT CONSTRUCTOR:
A constructor that accepts no parameters
is called the default constructor. The
example given above is of default
constructor.
PARAMETERIZED CONSTRUCTOR:
The constructor that can take arguments
are called parameterized constructor. In this
type constructor, we must pass the intial
values as arguments to the constructor
function when an object is declared. This
can be done in two ways:
By calling the constructor explicitly.
By calling the constructor implicitly. This is also called „shorthand method‟.
Example:
//program 4.1 class with constructors
class first
{
int m,n;
public:
//class with a constructor
class first
{ int m,n;
public:
first( ); // default constructor
declared
};
first :: first() //constructor defined
{ m=0; n=0;}
void main()
{
first a1; //object a1 created
}
first ( ) //default constructor
{ m = 0 ; n = 0 ; }
first ( int, int ) ; //parameterized constructor declared
void display ( )
{ cout << ”\n m::” << m ;
cout << ”\n n::” << n ;
}
};
first :: first( int x, int y) //parameterized constructor defined
{ m = x ; n = y ; }
void main( )
{
first a1 ; //default constructor called
first a2( 10, 20) ; //constructor called implicity
first a3 = first (100, 200 ) ; //constructor called explicity
cout << ”\nobject a1::\n” ;
a1.display( ) ;
cout << ”\nobject a2::\n” ;
a2.display ( ) ;
cout<< ”\nobject a3::\n” ;
a3.display( ) ; getch( ) ;
}
CONSTRUCTOR WITH DEFAULT ARGUMENTS:
It is possible to define constructor with default argument.Eg.:
first (int m , int n = 0) ;
It means the default value of n is zero. If we declare an object of class first as:
first a1(20); it assign the value 20 to m and 0 to n.
COPY CONSTRUCTOR:
The constructor that is used to declare and intialize an object from another object, is called copy
constructor. The process of intializing through a copy constructor is known as copy intialization. Copy
constructor can accept a reference to its own class as a parameter.
Example:
//program 4.2 class with copy constructor
class first
{
int m;
public:
first ( ) //default constructor
{ m = 0 ; }
first ( int a) //parameterized constructor
{ m = a ; }
first ( first & x) //copy constructor
{ m = x .m ; }
void display ( )
{ cout << ”\n m::” << m ; }
};
void main( )
{
first a1 ; //default constructor called
first a2 (10) ; //parameteized constructor called
first a3 (a2) ; //copy constructor called
first a4 = a2 ; //copy constructor called again
Output of program 4.1
output
object a1:
m=0, n=0
object a2:
m=10, n=20
object a3:
m=100, n=200
Output of program 4.2
output
object a1:
m=0
object a2:
m=10
object a3:
m=10
object a4:
m=10
cout << ”\nobject a1::\n” ;
a1.display( ) ;
cout << ”\nobject a2::\n”;
a2.display( );
cout << ”\nobject a3::\n”; a3.display( );
cout << ”\nobject a4::\n”;
a4.display( ) ; getch( ) ;
}
A reference variable has been used as an argument to the copy constructor. We cannot pass the argument
by value to a copy constructor.
When no copy constructor is defined, the complier supplies its own copy constructor.
DYNAMIC CONSTRUCTOR
The constructor can also be used to allocate memory while creating objects. This will enable the system
to allocate right amount of memory for each object when the object are not of the same size, thus resulting in
the saving memory. Allocation of memory to objects at the time of their construction is known as dynamic
construction of objects. The memory is allocated with the help of new operator.
Example:
//program 4.3 class with dynamic constructor
class string
{
char *name ; int length ;
public:
string( )
{ length = 0 ;
name = new char [ length + 1 ] ; } //one additional character for NULL value
string ( char *s)
{ length = strlen (s) ; name = new char [ length + 1 ] ;
strcpy ( name, s ) ; }
void show( )
{ cout << ”\n name:” << name ; }
void join ( string & a , string & b );
};
void string :: join(string & a, string & b)
{
length = a.length + b.length ;
delete name ;
name = new char [ length + 1 ] ; //dynamic allocation
strcpy (name, a.name) ; strcat( name, b.name);
}
void main( )
{
char *first = ”ncetc” ;
string name1 (first), name2 (“computer”) ;
string name3 (“institute”), s1, s2 ;
s1.join (name1,name2) ;
s2.join (s1,name3) ;
name1.show( ) ; name2.show( ) ;
name3.show( ) ; s1.show( ) ;
s2.show( ) ; getch( ) ;
}
Output of program 4.3
output
ncetc
computer
institute
ncetc computer
ncetc computer institute
NCETC COMPUTER EDUCATION
C++
17
DYNAMIC INTIALIZATION OF OBJECTS:
Class objects can be intialized dynamically too. It mens, the intial value of an object may be provided
during run time. One advantage of dynamic intialization is that we can provide various initalization formats,
using overloaded constructor. This provide the flexibility of using different format of data at run time
depending upon the situation.
Example:
//program 4.4 dynamic initailization of object
class first
{
int m,n;
public:
first( ) //default constructor
{ m = 0 ; n = 0 ; }
first ( int , int ) ; //parameterized constructor declared
void display( )
{ cout << ”\n m::” << m ; cout << ”\n n::”<< n ;
}
};
first :: first( int x , int y ) //parameterized constructor defined
{ m = x ; n = y; }
void main( )
{
first a1 ; //default constructor called
int x , y ;
cout << ”\nenter value of x and y:” ;
cin >> x >> y ;
first a2 ( x , y) ; //constructor called dynamically
first a3 (1 , 2) ; //constructor called staticaly
cout << ”\nobject a1::\n” ;
a1.display( ) ; cout << ”\nobject a2::\n” ;
a2.display( ) ; cout << ”\nobject a3::\n”;
a3.display( ) ; getch( ) ;
}
DESTRUCTOR:
A destructor is used to destroy the objects that have been created by a constructor. Like a constructor, a
destructor is member function whose name is the same as the class name but is preceded by a tilde sign(~).
A destructor never take any argument nor does it returns any value. It will be invoked implicitly by the
compiler upon exit from the program(or block or function as the case may be) to clean up storage that is no
longer accessrble. delete keyword is used to free the memory.
Example:
//program 4.5 class with destructor
int count = 0 ;
class alpha
{
public :
alpha( )
{ count + + ;
cout << ”\n no. of object created “ << count ; }
~ alpha( )
{ cout << ”\n no. of object destroyed “ << count ;
count-- ; }
};
void main( )
Output of program 4.4
input:
enter value of x and y: 100,300
output
object a1:
m=0, n=0
object a2:
m=100, n=300
object a3:
m=1, n=2
Output of program 4.5
Enter Main
no.of object created 1
no.of object created 2
Enter Block1
no.of object created 3
no.of object destoyed 3
Enter Block2
no.of object created 4
no.of object destoyed 4
Re-enter Main
no.of object destroyed 2
no.of object destroyed 1
{
cout << ”\n enter main\n”;
alpha a1,a2;
{ cout << ”\n enter block1\n” ; alpha a3 ;
}
{ cout << ”\n enter block2 \n” ; alpha a4 ;
}
cout << ”\n Re-enter main\n” ; getch( ) ;
}
Chapter 5 - Operator Overloading and Type Conversion
c++ tries to make the user-defined data types behave in much the same way as the built-in types. for
instance, c++ permits us to add two variables of user-defined types with the same syntax that is applied to
the basic types. This means that c++ has the ability to provide the operators with a special meaning for a
data type. The mechanism of giving such special meaning to an operator is known as operator-overloading.
Operator overloading provides a flexible option for the creation of new defination for most of the c++
operator. We can overload(give additional meaning to) all the c++ operators except the following:
Class member access operator( . , .*).
Scope resolution operator( :: ).
Size operator (sizeof).
Conditional operator( ?:).
The semantic of an operator can be extended, we cannot change its syntax.
To define an additional task to an operator, we must specify what it means in relation to the class to
which the operator is applied. This is done with the help of a special function, called operator function,
which describes the task. The general form of an operator function is:
where return type is the type of value returned by the specified operation and op is the operator being
overloaded. The op is preceded by the keyword operator. operator op is the function name.
Operator function must be either member functions(non-static) or friend functions. A basic difference
between them is that a friend function will have only one argument for unary operators and only one for
binary operators. This is because the object used to invoke the member function is passed implicitly and
therefore is available for the member function. This is not in the case of friend function. Argument may be
passed either by value or by reference.
Operator functions are declared in the class using prototypes as follows:
vector operator+(vector); //vector addition
vector operator-(); //unary minus
friend vector operator+(vector,vector); //vector addition
friend vector operator-(vector); //unary minus
int operator= =(vector); //comparision
friend int operator= =(vector,vector); //comparision
return type classname :: operator op (argument list)
{
function body
}
where vectoris a class-name.
The process of overloading involves the following steps:
1. Create a class that defines the data type that is to be used in the overloading operator.
2. Declare the operator function operator op() in the public part of the class. It may be either member
function or friend function.
3. Define the operator function to implement the required operations.
Overloaded operator functions can be invoked by expressions such as
op x or x op for unary operator and
x op y for binary operator.
op x (or x op) would be interpreted as operator op (x) for friend function.
Similarly, the expression x op y would be interpreted as either
x.operator op ( y ) in case of member function or
operator op ( x, y ) in case of friend function.
OVERLOADING UNARY OPERATOR:
Example:
//program 5.1 overloading of unary minus
class space
{
int x, y, z ;
public:
void get ( int , int, int ) ; void show ( ) ;
void operator - ( ) ; //overload unary minus (as a member fuction)
};
void space :: get ( int a, int b, int c)
{ x = a ; y = b ; z = c ; }
void space :: show ( )
{
cout << ” \n x = “ << x << ”\n y = “ << y << ”\n z = “ << z ;
}
void space :: operator – ( )
{
x = -x ; y = -y ; z = -z ;
}
void main( )
{
space s;
s.get (10 , -20 , 30 ) ;
s.show ( ) ; -s ;
cout << ”\n after unary minus: ” ;
s.show ( ); getch( );
}
Example:
//program 5.2 overloading of unary minus using friend function
class space
{
int x , y , z ;
public:
void get ( int , int , int ) ; void show ( ) ;
friend void operator - (space & s ) ; //overload unary minus (as a friend fuction)
} ;
void space :: get ( int a, int b, int c )
Output of program 5.1
output
x = 10
y = -20
z = 30
after unary minus:
x = -10
y = 20
z = -30
{ x = a ; y = b ; z = c ; }
void space :: show( )
{
cout << ”\n x = “<< x << ” \n y = “ << y << ”\n z = “ << z ;
}
void operator – ( space & s)
{
s.x = -s.x ; s.y = -s.y ; s.z = -s.z ;
}
void main( )
{
space s;
s.get(10,-20,30) ;
s.show( ); -s;
cout << ”\n after unary minus : ” ;
s.show( ) ; getch( ) ;
}
OVERLOADING BINARY OPERATOR:
Example:
//program 5.3 overloading of binary addition as a member function
class space
{
int x, y ;
public:
void get ( int a , int b )
{ x = a ; y = b ; }
void show( ) ;
space operator + ( space ) ; //overload binary plus (as a member function)
};
void space :: show( )
{
cout << ” \n x = “ << x << ”\n y = “ << y ;
}
space space :: operator + (space s)
{
space temp;
temp.x = x + s.x ; temp.y = y + s.y ;
return (temp) ;
}
void main( )
{
space s1, s2, s3 ;
s1.get (10, 20 ) ; s2.get (40, 40 ) ; s3=s1+s2;
cout << ”\ns1::” ; s1.show( ) ; cout << ”\ns2::” ; s2.show( ) ;
cout << ”\ns3::” ; s3.show( ) ; getch( );
}
//program 5.4 overloading of operators as a friend function
const int size = 3 ;
class vector
{
int v [size] ;
public:
vector( ) ; //constructs null vector
Output of program 5.2
output
x = 10
y = -20
z = 30
after unary minus:
x = -10
y = 20
z = -30
Output of program 5.3
output
s1:
x = 10
y = 20
s2:
x = 40
y = 40
s3:
x = 50
y = 60
vector ( int *x ) ; //constructs vector from array
friend vector operator * (int a, vector b ) ; //friend 1
friend vector operator * (vector b, int a ) ; //friend 2
friend istream & operator >>(istream & , vector & ) ;
friend istream & operator <<(ostream & , vector & ) ;
};
vector :: vector( )
{ for ( int i = 0 ; i < size ; i ++ )
{ v [i] = 0 ; }
}
vector :: vector ( int * x )
{ for ( int i = 0 ; i < size ; i ++ )
{ v [ i ] = x [ i ] ; }
}
vector operator * ( int a, vector b )
{ vector c;
for ( int i = 0 ; i < size ; i ++ )
{ c.v [ i ] = a * b.v [ i ] ; }
return c;
}
vector operator * ( vector b , int a )
{ vector c;
for ( int i = 0 ; i < size ; i ++ )
{ c.v [ i ] = b.v[ i ] * a ; }
return c ;
}
istream & operator >> (istream & din , vector & b )
{ for ( int i = 0 ; i < size; i ++ )
{ din >> b.v [ i ] ; }
return(din) ;
}
ostream & operator << ( ostream & dout , vector & b )
{ dout << ” ( “ << b.v [ 0 ] ;
for ( int i = 1; i < size ; i ++ )
{ dout << ”, “ << b.v [ i ] ; }
dout << ” ) “ ; return ( dout ) ;
}
int x [ size ] = { 2, 4, 6 };
void main( )
{
vector m ; //invoke constructor 1
vector n = x ; //invoke constructor 2
cout << ”Enter elements of vector m:” ;
cin >> m ; //invoke operator >>( )
cout << ”\n”;
cout << ”\n m = ”<< m << ”\n” ; //invoke operator <<( )
vector p , q ;
p = 2 * m ; //invoke friend 1
q = n * 3 ; //invoke friend 2
cout << ”\n p = “ << p << ”\n” ; //invoke operator <<( )
cout << ”\n q = “ << q <<”\n” ; getch( ) ;
}
Output of program 5.4
output
Enter elements:
5 10 15
m = ( 5, 10, 15)
p = ( 10, 20, 35)
q = ( 4, 8, 12)
Why use friend function rather than member function
There are certain situations where we would like to use a friend function rather than member function.
For instance, consider a situation where we need to use two different types of operands for a binary operator,
say, one an object and another a built-in-type data as shown below:
a = b + 2; ( or a = b * 2 ; )
where a and b are objects of the same class. This will work for a member function but the statement
a = 2 + b ; ( or a = 2 * b ; )
will not work. This is because the left-hand operand which is responsible for invoking the member
function should be an object of the same class. However friend function allows both apporaches because, an
object need not be used to invoke a friend function but can be passed as an argument. So, we can use a
friend function with a built-in type data as the left-hand operand and an object as the right-hand operand.
MANIPULATION OF STRING USING OPERATORS
Strings can be defined as class objects which can be then manipulated like the built-in types. Since the
strings vary greatly in size, we use new to allocate memory for each string and a pointer variable to point to
the string array.
example:
//program 5.5 mathematical operator on strings
class string
{
char *p ; int len ;
public:
string( )
{ len = 0 ; p = 0 ; } //create null string
string( const char *s)
{ len = strlen(s) ; p = new char[len + 1] ; strcpy (p , s ); }
string( const string &s)
{ len = s.len ; p = new char [len + 1] ;
strcpy ( p , s.p ) ;
}
~string ( ) { delete p ; }
friend string operator + ( const string & s, const string & t ) ;
friend int operator <= ( const string & s, const string & t ) ;
friend void show (const string s) ;
};
string operator + ( const string & s, const string & t)
{ string temp ;
temp.len = s.len + t.len; temp.p = new char [ temp.len + 1] ;
strcpy ( temp.p , s.p ) ; strcat ( temp.p , t.p ) ; return (temp);
}
int operator <= ( const string & s , const string & t )
{ int m = strlen( s.p ) ; int n = strlen( t.p ) ;
if ( m <= n) { return (1) ; }
else { return (0 ) ; }
}
void show( const string s )
{ cout << s.p ; }
void main( )
{
string s1 = ”ncetc”; string s2 = “computer”; string s3 = “institute” ;
string t1 ,t2, t3;
t1 = s1 ; t2 = s2 ; t3 = s1 + s3 ;
cout << “\n t1 = “; show ( t1 );
cout << “\n t2 = “; show ( t2 );
Output of program 5.5
output
t1 = ncetc
t2 = computer
t3 = ncetc institute
ncetc smaller than
ncetc institute
cout << “\n t3 = “; show ( t3 );
if ( t1 <= t3 )
{ cout << “\n”; show (t1 );
cout << ” smaller than “; show (t3);
}
else
{ cout << “\n”; show (t3 );
cout << ” smaller than “; show (t1);
} getch();
}
RULES FOR OVERLOADING OPERATORS:
There are some restrication and limitations in overloading them. Some of them are:
Only existing operators can be overloaded. New operator cannot be created.
The overloaded operator must have at least one operand that is of user-defined type.
We cannot used friend functions to overload certain operators. These are:
= Assignment operator
( ) Function call operator
[ ] Subscripting opeartor
- > Class member access opeartor
Chapter 6 - Inheritance : Extending Class
c++ supports the concept of reusability. The c++ classes can be reused in several ways. This is basically
done by creating new classes, reusing the properties of the existing ones. The mechanism of deriving a new
class from the old one is called inheritance ( or dervation ). The old class is reffered to as the base class and
the new one is called the derived class or subclass.
The derived class inherits some of all of the traits from the base class. A class can also inherit properties
from more than one class or from more than one level. On the basis of derivation, inheritance is of following
type:
single level inheritance
multiple inheritance
multilevel inheritance
Hierarchical inheritance
Hybrid inheritance
DEFINING DERIVED CLASSES
A derived class can be defined by specifying its relationship with the base class in addition to its own
details.The general form of defining a derived class is:
The colon : indicates that the derived-class-name is derived from the base-class-name. The visibility-
mode is optional and, if present, may be private, public or protected. The default visibility-mode is private.
Visibility mode specifies whether the features of the base class are privately derived or publicly derived.
class derived-class-name : visibility-mode base-class-name
{
//members of derived class
};
Base class
visibility
Derivied class visibility
Public
derivation
Private
derivation
Protected
derivation
Private Not inheritaed Not inheritaed Not inheritaed
Protected Protected Private Protected
Public Public Private Protected
When a base class is privately inherited by a derived class, „public members‟ of the base class
become „private member‟ of the derived class and therefore the public members of the base class can
be accessed by the member functions of the derived class. They are inacessible to the object of the
derived class. The result is that no member of the base class is accessible to the objects of the derived
class.
When a base class is publicly inherited, „public members‟ of the base class become „public member‟
of the derived class and therefore they are accessible to the objects of derived class.
When a base class is protectedly inherited, „public members‟ of the base class become „protected
member‟ of the derived class and therefore they are accessible to the objects of derived class.
In all the cases, the private members are not inherited and therefore, the private members of a base
class will never become the members of its derived class.
In inheritance, some of the base class data elements and member functions are inherited into derived
class. We can add our own data and member functions to extends the functionality of the base class.
Single level inheritance:
example:
// 6.1 single Level inheritance : public
class parent
{
int a ; //private ; not inheritable
public :
int b ; //public ; ready for inheritance
void get_ab ( ) ; get_a ( ) ; void show_a( ) ;
};
class child : public parent //public derivation
{ int c;
public:
void mul ( ) ; void display ( ) ;
};
void parent :: get_ab( )
{ a = 5; b = 10 ; }
int parent :: get_a ( )
{ return a ; }
void parent :: show_a ( )
{ cout << ”\n a = “ << a ; }
void child :: mul ( )
{ c = b * get_a ( ) ; }
void child :: display ( )
{ cout<<”\n a = “<< get_a ( ) ;
cout<<”\n b = “<<b <<”\n c = “<<c;
}
void main( )
{ child c1;
c1.get_ab ( ); c1.mul ( );
c1.show_a( ); c1.display ( );
Output of program 6.1
output
a = 5
a = 5
b = 10
c = 50
a = 5
b = 20
a = 100
Parent Class
Child Class
Single Level Inheritance
c1.b = 20 ; c1.mul ( );
c1. display ( ); getch ( );
}
The class child is a public derivation of the base class parent. Therefore, child inherits all the public
members of the parent and retains their visibility. Thus a public member of the base class parent is also a
public member of the derived class child. The private members of parent cannot be inherited by child.
example:
// 6.2 single inheritance : private
class parent
{
int a; //private ; not inheritable
public:
int b; //public ; ready for inheritance
void get_ab( ) ; void get_a ( ) ; void show_a ( ) ;
};
class child : private parent //private derivation
{ int c;
public:
void mul ( ) ; void display ( );
};
void parent :: get_ab ( )
{ cout << ”\nenter value of a and b :: ” ;
cin >> a >> b;
}
int parent :: get_a ( )
{ return a ; }
void parent :: show_a ( )
{ cout << ” \n a = “ << a ; }
void child :: mul ( )
{ get_ab( ) ;
c = b * get_a( ) ; // „a‟ cannot be used directly
}
void child :: display ( )
{
show_a( ); // outputs value of „a‟
cout << ” \n b = “<< b << ”\n c = “ << c ;
}
void main( )
{
child c1;
// c1.get_ab ( ); // won‟t work
c1.mul ( );
// c1.show_a ( ); // won‟t work
c1.display ( );
// c1.b = 20 ; // won‟t work ; b has become private
c1.mul ( );
c1. display ( ); getch ( );
}
If a base class and a derived class define a function of the same name, and a derived class object invokes
the function, then the derived class function supersedes the base class fuction defination. The base class
function will be called only if the derived class does not redefine the function.
Output of program 6.2
output
enter value of a and b :: 5
10
a = 5
b = 10
c = 50
a = 12
b = 20
a = 240
A
B
derived class C
father
child
Base class Grandfather
Intermediate
Base class
MAKING A PRIVATE MEMBER INHERITABLE
Private member can be inheritable by modifying the visibility limit of the private member by making it
public. This would make it accessible to all other functions of the program, thus taking away the advantage
of the data hiding.
c++ provides a third visibility modifier, protected, which serve a limited purpose in inheritance. A
member declared as protected is accessible by the member functions within its class and any class
immediately derived from it. It cannot be accessed by the functions outside these two classes. A class can
now use all the three visibility modes as following:
class alpha
{
private : // visible to member functions within its class
-------------- //member declaration
protected : // visible to member functions of its own and derived class
-------------- //member declaration
public : // visible to all functions in the program
-------------- //member declaration
};
When a protected member is inherited in public mode, it becomes protected in the derived class too and
therefore is accessible by the member functions of the derived class. It is also ready for further inheritance.
A protected member, inherited in the private mode derivation, becomes private in the derived class.
Although it is available to the member functions of the derived class, it is not available for further
inheritance ( since private members cannot be inherited ).
These functions can have access to private and protected members of a class :
1. A function that is a friend of the class.
2. A member function of a class that is a friend of the class.
3. A member function of a derived class.
While the friend functions and the member functions of a friend class can have direct access to both the
private and protected data, the member functions of a derived class can directly access only the protected
data.
Multilevel inheritance:
In multilevel inheritance, a class is derived
from another derived class.
example:
// 6.3 multilevel inheritance
class student
{
protected:
int r_no ; //private ; not inheritable
public:
void get_number( int a )
{ r_no = a ; }
void put_number( )
{ cout << ” Roll number is :: “ << r_no ; }
};
class test : public student //public derivation ; first level derivation
{
protected:
float sub1, sub2 ;
public:
void get_marks ( float, float ) ; void put_marks( ) ;
};
B-1 B-2 B-n
D
void test :: get_marks ( float a , float b )
{ sub1 = a ; sub2 = b; }
void test :: put_marks ( )
{ cout << ” \n Marks in Sub1 is :: “ << sub1 ; cout << ” \n Marks in Sub2 is :: “ << sub2;
}
class result : public test //public derivation ; second level derivation
{ float total ;
public:
void display ( );
};
void result :: display ( )
{ total = sub1 + sub2 ;
put_number ( ) ; put_marks ( );
cout<< “\nTotal = “<< total ;
}
void main( )
{
result s1;
s1.get_number ( 100 ) ;
s1.get_marks ( 56.0 , 75.0 ) ;
s1. display ( ); getch ( ) ;
}
Multiple inheritance:
In multiple inheritance, a class can inherits the
attributes of two or more classes. Multiple inheritance
allows us to combine the features of several existing
classes as a starting point for defining new classes.
The synax of a derived class with multiple base class is
as follows:
example:
// 6.4 multiple inheritance
class M
{ protected:
int m ; //private ; not inheritable
public:
void get_m( int x)
{ m = x ; }
};
class N
{ protected:
int n ; //private ; not inheritable
public:
void get_n ( int x )
{ n = x ; }
};
class P : public M , public N //public derivation ;
{ public:
Output of program 6.3
output
Roll Number = 100
Marks in Sub1 = 56.0
Marks in Sub2 = 75.0
Total = 131.0
class D : visibility B-1, visibility B-2 , visibility B-n
{
body of D //members of class D
};
Students
Arts Engineering Medical
Mech. Elec. Civil
Multiple , Multilevel Inheritance
Test
Student
Sports
Result
void display ( ) ;
};
void P :: display ( )
{ cout << ” \n m :: “ << m <<” \n n :: “ << n ;
cout << “\n m * n = “<< m * n ;
}
void main( )
{
P s1;
s1.get_m ( 100); s1.get_n ( 5 );
s1. display ( ); getch ( );
}
AMBIGUITY RESOLUTION IN INHERITANCE:
Occasionally, we may face a problem in using the multiple inheritance, when a function with the same
inheritance appears in more than one base class.
class M
{ public :
void display ( ) { cout << ”class M “; }
};
class N
{ public :
void display ( ) { cout << ”class N “; }
};
when class M and class N both are inherited by another class D , which display ( ) function is used by
the derived class. We can solve this problem by defining a named instance within the derived class, using
the class resolution operator with the function as shown below:
class D : public M , public N
{ public:
void display ( )
{ M :: display ( ) ; }
};
We can now use the desired class as follows :
void main ( )
{ D d1 ; d1.display ( );
d1.N :: display ( ) ; getch ( );
}
Hierarchical inheritance
Another interesting application of inherirance is to use it as a support to the hierarchical design of a
program.
HYBRID INHERITANCE:
There could be situations where we need to apply
two or more types of inheritance to design a program.
Like this :
Output of program 6.4
output
m = 100
n = 5
m * n = 500
example:
// 6.5 hybrid inheritance
class student
{ protected :
int r_no ; //private ; not inheritable
public:
void get_number ( int a )
{ r_no = a ; }
void put_number( )
{ cout << ” Roll number is :: “ << r_no ; }
};
class test : public student //public derivation ; first level derivation
{ protected:
float sub1, sub2 ;
public:
void get_marks ( float a , float b )
{ sub1 = a ; sub2 = b; }
void put_marks ( )
{ cout << ” \n Marks in Sub1 is :: “ << sub1 ;
cout << ” \n Marks in Sub 2 is :: “ << sub2 ; }
};
class sports
{ protected :
float score ;
public:
void get_score ( float a )
{ score = a ; }
void put_score( )
{ cout << ” \n Sport wt is :: “ << score ; }
};
class result : public test , public sports //public derivation ; second level derivation
{ float total ;
public:
void display ( );
};
void result :: display ( )
{ total = sub1 + sub2 + score ;
put_number ( ); put_marks ( );
put_score ( );
cout << “\nTotal = “ << total ;
}
void main( )
{
result s1;
s1.get_number ( 100);
s1.get_marks ( 56.0 , 75.0 );
s1.get_score (6.0 ); s1. display ( ); getch ( );
}
VIRTUAL BASE CLASS:
Consider a situation where all the three kinds of inheritance, namely, multiple , multilevel, and
hierarchical inheritance, are involved. This is shown below:
Output of program 6.5
output
Roll Number = 100
Marks in Sub1 = 56.0
Marks in Sub2 = 75.0
sport wt. = 6
Total = 137.0
The child has two direct base classes parent1 and parent2 which themselves have a common base class
grandfather. The child inherits the traits of grandparent via two seprate paths. It can also inherits directly as
shown by the broken line. The grandparent is sometimes reffered to as indirect base class.
This inheritance by the child might pose some problems. All the public and protected member of
grandparent are inherited into child twice, first via parent 1 and again via parent 2. This means child have
duplicate sets of the members inherited from grandparent.
The duplication of inherited members due to these multiple paths canbe avoided by making the common
base class (ancestor class ) as virtual base class while declaring the direct or intermediate base classes using
virtual keyword.
example:
// 6.6 virtual base class
class student
{ protected:
int r_no ; //private ; not inheritable
public:
void get_number ( int a )
{ r_no = a ; }
void put_number ( )
{ cout << ” Roll number is :: “ << r_no ; }
};
class test : virtual public student //public derivation ; first level derivation
{ protected:
float sub1, sub2 ;
public:
void get_marks ( float a , float b )
{ sub1 = a ; sub2 = b; }
void put_marks( )
{ cout << ” Marks Obtained :”<<\n Marks in Sub1 is :: “ << sub1 ;
cout << ” \n Marks in Sub1 is :: “ << sub1 ; }
};
class sports : virtual public student
{ protected:
float score ;
public:
void get_score ( float a )
{ score = a ; }
void put_score( )
{ cout << ” \n Sport wt is :: “ << score ; }
};
class result : public test, public sports //public derivation ; second level derivation
{ float total ;
public:
Grandparent
Child
Parent 1 Parent 2
void display ( );
};
void result :: display ( )
{ total = sub1 + sub2 + score ;
put_number ( ); put_marks ( );
put_score ( );
cout<< “\nTotal = “ << total ;
}
void main( )
{
result s1;
s1.get_number ( 100);
s1.get_marks ( 56.0 , 75.0 );
s1.get_score (6.0 ); s1. display ( ); getch ( );
}
keyword virtual and public can be used in any order.
ABSTRACT CLASSES
An abstract class is one that is not used to create objects. An abstract class is designed only to act as a
base class ( to be inherited by other classes ). In the program 6.6, student class is an abstract class since it
was not used to create any object.
CONSTRUCTOR IN DERIVED CLASSES:
The constructors play an important role in intializing objects. One important thing to note here is that, as
long as no base class constructor takes any arguments, the derived class need not have a comstructor
function. If any base class contains a constructor with one or more arguments, then it is mandatory for the
derived class to have a constructor and pass the arguments to the base class constructors. When both the
base and derived classes contains constructors, the base constructor is executed first and then the constructor
in the derived class is executed.
In the case of multiple inheritance, the base classes are constructed in the order in which they appear in
the declaration of the derived class.
In multilevel inheritance, the constructors will be executed in the order of inheritance.Since the derived
class takes the responsibility of supplying intial values to its base classes, we supply the intial values that are
required by all the classes together, when a derived class object is declared.
The header line of derived constructor function contains two parts separated by a colon ( : ). The first
part provides the declaration of the arguments that are passed to the derived constructor and the second part
lists the function calls to the base constructors.
Synax:
example :
class D : public A, public B
{ int m ;
public:
D ( int a1, int a2, int a3, int a4 int a5 ) : A ( a1, a2 ) , B ( a3, a4 )
{ m = a4 ; }
};
Output of program 6.6
output
Roll Number = 100
Marks Obtained:
Marks in Sub1 = 56.0
Marks in Sub2 = 75.0
sport wt. = 6
Total = 137.0
constructor ( arglist ) : intialization – section
{ assignment –section
}
The constuctors for virtual base classes are involved before any non-virtual base classes. If there are
multiple virtual base classes, they are invoked in the order in which they are declared. Any non-virtual bases
are then constructed before the derived class constructor is executed .
example :
//program 6.7
class alpha
{ int x ;
public :
alpha ( int l )
{ x = l ; cout << “\n alpha constructed “; }
void show_alpha ( )
{ cout << “\n x = “ << x ; }
};
class beta
{ float p ,q ;
public :
beta ( float a , float b )
{ p = a ; q = b ; cout << “\n beta constructed “; }
void show_beta ( )
{ cout << “\n p = “ << p << “\n q = “ << q; }
};
class gamma : public beta , public alpha
{ int u ,v ;
public :
gamma ( int a , int b , float c ) : alpha ( a * 2 ) , beta ( c , c ) , u ( a )
{ v = b ; cout << “\n gamma constructed “; }
void show_gamma ( )
{ cout << “\n u = “ << u << “\n v = “ << v ; }
};
void main ( )
{ gamma g ( 2 , 4 ,2.5 );
cout << “\n Display member values :” ;
g.show_alpha ( ); g.show_beta ( );
g.show_gamma ( ); getch ( );
}
Method of inheritance Order of execution
class B : public A
{
};
A( ) ; base constructor
B( ) ; derived constructor
class C : public B , public A
{
};
B( ) ; base constructor (first)
A( ) ; base constructor (second)
C( ) ; derived constructor
class C : public B , virtual public A
{
};
A( ) ; virtual base
B( ) ; ordinary base
C( ) ; derived constructor
Output of program 6.7
output
beta constructed
alpha constructed
gamma constructed
Display member values:
x = 4 p = 2.5 q = 5
u = 2 v = 4
Polymorphism
Compile time
polymorphism
Run time
polymorphism
Function
overloading
Operator
overloading
Virtual
function
Chapter 7 - Pointers, Virtual Functions and Polymorphism
Polymorphism is one of the important feature of OOP. It simply means „one name, multiple forms‟.
Polymorphism is of two type:-
1. Compile time polymorphism:- The overloaded member functions are „selected‟ for invoking by
matching arguments, both type and number. This information is known to the compiler at the
compile time and, therefore , compiler is able to select the appropriate function for a particular call at
the compile time itself. This is called „early binding or static binding or static linking‟. Early binding
simply means that an object is bound to its finction call at compile time.
2. Run time polymorphism:- In inheritance, when a parent class and a child class both have its own
function of same name, there may be a problem to decide which function should called. It can be
one if the approciate member function are selected while the program is running. This is known as
Run time polymorphism. At run time, when it is known what class objects are under consideration,
the approcpriate version of the function is invoked. Since the function is linked with a particular
class much later after the compilation, this process is termed as „late binding or dynamic binding‟.
Dynamic binding means
the selection of
appropriate function is
done by dynamically at
run time.
Dynamic binding requires the
use of pointers to objects. Run
time polymorphism is achieved
only when a virtual function is
accessed through to the base
class.
Pointers to objects
object pointers are useful in creating objects at runtime. we can also use an object pointer to access the
public members of an object. Member functions can be used in two ways , by using the dot operator and the
object, and another by using arrow operator and the object pointer.
example : program 7.1
class item
{
int code ; float price ;
public:
void getdata ( int a , float b )
{ code = a ; price = b ; }
void show ( )
{ cout << “ \ncode : “ << code ;
cout << “ \n price : “ << price ;
}
};
const int size = 2 ;
void main ( )
{
item *p = new item [ size ];
item * d = p ;
int x , i ; float y ;
Output of program 7.1
output
enter code and price for item
40 500
40 500 enter code and price for
item
41 600
item 1 :
code : 40 price : 500
code : 41 price : 600
for ( i = 0 ; i <size ; i++)
{
cout << “ enter code and price for item : “ ;
cin >> x >> y ;
p -> getdata ( x ,y ) ;
p ++ ;
}
for ( i = 0 ; i <size ; i++)
{
cout << “ \n item : “ << i + 1 ;
d -> show ( ) ;
d ++ ;
}
getch ( ) ;
}
this pointer
c++ uses a unique keyword called this to represent an object that invokes a member function. this is a
pointer that points to the object for which this functio was called. This unique pointer is automatically
passed to a member function when it is called. The pointer this acts as an implicit argument to all the
member functions.
example : program 7.2
//program for this pointer
class person
{
char name [20 ] ; float age ;
public :
person ( char * s , float a )
{ strcpy ( name , s ) ; age = a ;
}
person & person :: greater ( person & x )
{ if ( x .age > =age )
return x ;
else
return *this ;
}
void display ( )
{ cout << “\n name : “<< name ;
cout << “\n age : “<< age ;
}
};
void main ( )
{
person x1 (“ Rahul “ , 37. 50 ) ;
person x2 (“ Raj “ , 29. 00 ), x3 (“ Ram “ , 40. 25 ) ;
person x = x1 . greater ( x3 );
cout << “ \n elder person is : “ ;
x .display ( );
x = x1 . greater ( x2 );
cout << “ \n elder person is : “ ;
x .display ( ) ;
getch ( ) ;
}
Output of program 7.2
output
elder person is :
name : Ram
age : 40.25
elder person is :
name : Rahul
age : 37.50
POINTERS TO DERIVED CLASSES
We can use the pointers not only to the base objects but also to the objects of derived classes. Pointers to
objects of a base class are type- compatible with pointers to objects of a derived class. Therefore, a single
pointer variable can be made to point to objects belonging to different classes.
Although c+ + permits a base pointer to point to any object derived from that base, the pointer cannot be
directly used to access all the members of the derived class.
example :
//program 7.3 for pointer to derived class
class base
{ public :
int b ;
void show ( )
{ cout << “ \n b = “ << b ; }
};
class child : public base
{ public :
int d ;
void show ( )
{ cout << “ \n b = “ << b; cout << “ \n d = “ << d;
}
};
void main ( )
{
base * bptr , b1;
bptr = & b1 ;
bptr - > b = 100 ;
cout << “\n bptr points to base object :” ;
bptr -> show ( );
child c1;
bptr = & c1 ;
bptr - > b = 200 ;
cout << “\n bptr points to child object :” ;
bptr -> show ( );
child * cptr ;
cptr = & c1 ;
cptr - > d = 300 ;
cout << “\n cptr is child type pointer :” ;
cptr -> show ( );
cout << “\n using ( ( child * ) bptr ) ” ;
( ( child * ) bptr ) -> d = 400 ;
( ( child * ) bptr ) - > show ( ) ;
getch ( ) ;
}
virtual function
Polymorphism refers to the property by which objects belonging to different classes are able to respond
to the same message, but in different forms. An essantial requirement of polymorphism is therefore the
ability to refer to objects without any regard to their classes. This necessitates the use of a single pointer
variable to refer to the objects of different classes. We use the pointer to base class to refer to all the derived
objects. But a base pointer, even when it is made to contain the address of a derived class, always executes
the function in the base class.
The compiler simply ignores the contents of the pointer and choose the member function that matches
the type of the pointer. This problem can be solve by using virtual function.
Output of program 7.3
output
bptr points base object
b = 100
bptr now points to child object
b = 200
cptr is child type pointer
b = 200
d = 300
using ( ( child * ) bptr )
b = 200
d = 400
When we use the same function in both the base and derived classes, the function in base class is
declared as virtual using the keyword virtual preceding its normal declaration. When a function is made
virtual, c++ determines which function to use at run time based on the type of object pointed by the base
pointer, rather than the type of the pointer.
example :
//program 7.4 for virtual function
class base
{
public :
void display ( ) { cout << ”\n display base “ ; }
virtual void show ( ) { cout << ”\n show base “ ; }
};
class derived : public base
{
public :
void display ( ) { cout << ”\n display derived “ ; }
virtual void show ( ) { cout << ”\n show derived “ ; }
};
void main ( )
{
base b , *bptr ; derived d;
cout << “ \n bptr points to base \n “; bptr = & b ;
bptr - > display ( ); //call base version
bptr - > show ( ); //call base version
cout << “ \n bptr points to derived \n “; bptr = & d ;
bptr - > display ( ); //call base version
bptr - > show ( ); //call derived version
getch ( );
}
example : runtime polymorphism
//program 7.5 for run time polymorphism by virtual function
class media
{
protected:
char title [50 ] ; float price ;
public :
media ( char * s , float a )
{ strcpy ( title , s ) ; price = a ; }
virtual void display ( )
{ } //empty virtual function
};
class book : public media
{
int pages ;
public :
book ( char * s , float a , int p ) : media( s, a)
{ pages = p ; }
void display ( ) ;
};
class tape : public media
{
float time ;
public :
tape( char * s , float a , float t : media( s, a)
{ time = t ; }
void display ( ) ;
};
void book :: display ( )
{
cout << “ \n Title : “ << title ;
cout << “ \n Pages : “ << pages ;
cout << “ \n Price : “ << price ;
}
void tape :: display ( )
{
cout << “ \n Title : “ << title ;
cout << “ \n Play time : “ << time << “mins “ ;
cout << “ \n Price : “ << price ;
}
void main ( )
{
char * title = new char [30 ] ;
int pages ; float price , time ;
// book details
cout << “ \n Enter book details :” ;
cout << “\n Title :” ; cin >> title ;
cout << “\n Price :” ; cin >> price ;
cout << “\n Pages :” ; cin >> pages ;
book book1 ( title , price , pages ) ;
// tape details
cout << “ \n Enter tape details :” ;
cout << “\n Title :” ; cin >> title ;
cout << “\n Price :” ; cin >> price ;
cout << “\n Play time ( mins ) :” ; cin >> time ;
tape tape1 ( title , price , time ) ;
media * list [ 2 ];
list [ 0 ] = & book1 ;
list [ 1 ] = & tape1 ;
cout << “ \n media details “ ;
cout << “ \n ...book... “ ;
list [ 0 ] -> display ( );
cout << “ \n ...tape... “ ; list [ 1 ] -> display ( );
getch ( );
}
Rules for virtual function
when virtual functions are created for implementing late binding, we should observe some basic rules
that satisfy the compiler requirements:
1. The virtual function must be the member of some class.
2. They cannot be static members.
3. They are accessed by using object pointer.
4. A virtual function can be a friend of another class.
5. A virtual function in a base class must be defined, even though it may not be used.
Output of program 7.5
output
Enter book details :
Title : let us c
Price : 100
Pages : 200
Enter tape details :
Title : computing_concept
Price : 90
Play time (mins) : 55
media details:
...book...
Title : let us c
Price : 100
Pages : 200
...tape...
Title : computing_concept
Price : 90
Play time (mins) : 55
6. The prototype of the base class version of a virtual function and all the derived class versions must
be identical. If two functions with the same name have different prototype, c++ considers them as
overloaded finctions, and the virtual function mechanism is ignored.
7. We cannot have virtual constructor, but we can have virtual destructor.
8. While a base pointer can point to any type of the derived object, the reverse is not true. It‟s meaning ,
we cannot use a pointer to a derived class to access an object of the base type.
9. When a base pointer points to a derived class, incrementing or decrementing it will not make it to
point to the next object of the derived class. It is incremented or decremented only relative to its base
type. Therefore, we should not use thid method to move the pointer to the next object.
PURE VIRTUAL FUNCTION ( ABSTRACT BASE CLASS )
A pure virtual function is a function declared in a base class that has no defination relative to the
base class. In such cases, the compiler requires each derived class to either define the function or
redeclare it as a pure virtual function. A class containing pure virtual functions cannot be used to declare
any object of its own. Such classes are called abstract base classes.
The main objective of an abstract base class is to provide some traits to the derived classes and to
create a base pointer required for achieving run time polymorphism. Pure virtual functions are also
called “do-nothing” function.
A “do-nothing” function may be defined as follows :
Chapter 8 - Managing Console I/O Operation
C++ uses concepts of streams and stream classes to implement its I/O operations with the console and
disk files.
C++ STREAMS
A stream is a sequence of bytes. It acts either as a source from which the input data can be obtained or as
a destination to which the output data can be sent. The source stream that provides data to the program is
called the input stream and the destination streams that received the output from the program is called the
output stream.
The data in the input streams can come from the keyboard or any other storage device and The data in
the output streams can go to the screen or any other storage device.
C++ STREAMS CLASSES:
c++ streams classes are declared in header file iostream.
UNFORMATTED I/O OPEREATIONS
overloaded operator >> and <<
cout << “hello “;
cin > a ;
put( ) and get ( ) function
The class istream and ostream define two member functions get ( ) and put( ) resepectively to handle the
single character input / output .
There are two version of get ( ) function:-
get (char * ) version assigns the input character to its argument and get (void ) version returns the input
character.
Example
// program 8.1 use of get ( ) and put ( ) function
void main ( )
{
virtual void show ( ) = 0;
int count = 0 ; char d ;
cin . get ( d) ;
cout << “\n input text :\n” ;
while ( d ! = „ \n ‟ )
{ cout . put ( d ) ;
d = cin . get ( ) ; count ++ ;
}
cout << “ \n number of characters = “ << count ;
getch ( ) ;
}
getline( ) and write( ) function
These function are used to handle a whole line of text that ends with a newline character (enter key ).
syntax:
here line is text or string variable name and size is the maximum number of character to be read / write.
Example
void main ( )
{ int size = 20 ; char city [20 ];
cout <<” \n enter city name : \n” ;
cin .getline ( city , size ) ; cout <<” \n “;
//cout .write ( city ,size ) ;
cout << city; getch ( ) ;
}
FORMATTED CONSOLE I/O OPERATIONS
c++ supports a number of features that could be used for formatting the output. These features includes :
1. ios class functions and flags
2. Manipulators.
3. User-defined output functions.
ios class functions and flags
Function Task
width ( ) To specify the required field size for displaying an output values.
precision ( ) To specify the number of digits to be displayed after the decimal
point of a float value.
fill ( ) To specify a character that is used to fill the unused portion of a
field.
width ( )
where w is the number of columns (field width ) . The output will be printed in a field of w characters
wide at the right end of the field.
precision ( )
where d is the number of digits to the right of the decimal point.
Output of program 8.1
output
input text
Disha
output
Disha
number of characters = 5
cin.getline ( line , size ) ;
cout.write ( line , size ) ;
cout.width ( w ) ;
cout.precision ( d ) ;
ostream & manipulator ( ostream & output )
{
.........
.........
return output ;
}
( code )
fill ( )
where ch is the character which is used for filling the unused positions.
Example
void main ( )
{
int s = 450 ; float d = 633.8945 ; char v = „$‟ ;
cout . fill ( v ) ;
cout . precision ( 3 ) ; cout << “ \n “ << d ;
cout . width ( 7 ) ; cout << “ \n “ << s ;
cout . width ( 15 ) ; cout << “ \n “ << s ;
getch ( ) ;
}
Managing output with manipulators.
Function Equivalent ios function
setw ( int w ) width ( )
setprecision ( int d) precision ( )
setfill ( char c) fill ( )
Example
void main ( )
{
int s = 450 ; float d = 633.8945 ; char v = „$‟ ;
cout << “ \ n ” << setfill ( v ) ;
cout << “ \ n ” << setprecision ( 3 ) << d ;
cout << “ \ n ” << setw ( 7 ) << s ; cout << “ \ n ” << setw (20 ) << s ;
cout << “ \ n ” << setfill ( „^‟ ) ;
cout << “ \ n ” << setw ( 10 ) << setprecision ( 2 ) << 1.2345 ; getch ( ) ;
}
DESINGING OUR OWN MANIPULATOR
We can design our own manipulators for certain
special purpose. The general form for creating a
manipulator without any arguments is :
Example
#include < iostream . h >
#include < iomanip . h >
ostream & currency ( ostream & output )
{ output << “Rs “ ; return output ;
}
void main ( )
{
cout << currency <<7864.5 ;
getch();
}
Assessment: Regular Tests, Assignments, and Final Project Evaluation
Certification: Certificate of Completion from Disha Institute
Number of Days Depends on your practice and feedback. The more you practice and review your work, the faster you will complete the course.
For Batch time and Fess contact to Below Address and Number.
(MCA / Bsc. I.T / ‘A’ / ‘O’ / CCC / Govt. Certified Domain Skill Trainer )
Disha Institute 153 Vijay Nagar Opp. Rg Pg College W.K Road Meerut
(9411617329 , 9458516690)
Comments
Post a Comment