Object Oriented Prog.
Object Oriented Prog.
Object Oriented Prog.
A type of programming in which programmers define not only the data type of a data structure, but
also the types of operations (functions) that can be applied to the data structure. In this way, the data structure
becomes an object that includes both data and functions.
Object Oriented Programming treats data as a critical element and does not allow to flow freely
around the system. It ties data more closely to the functions that operate on it and protects it from
unintentional modification by other functions. OOP allows us to decompose a problem into a number of
entities called Objects and then build data and functions around those entities. Combinations of data and
functions make up an object.
C++ is an object oriented language, It was developed by Bjarne Stroustrup at AT & T Bell Laboratories in
USA, in the early 1980. C++ is a superset of C.
A class may be thought of as a ‘data type’ and an object as a ‘variable’ of that type. Once a class has
been defined, we can create any number of objects belonging to that class. Each object is associated with
the data of type class with which they are created. A class is thus a collection of objects of similar type. A
class is a group of objects that share common properties and relationships. Class declaration defines a new
type that links code and data. It binds the data and its associated functions together. It allows the data to be
hidden from external use. For example, mango, apple and orange are the members of class fruit. Classes
are user-defined data types and behave like the built-in types of a programming language.
A class specification has 2 parts
1. Class declaration,
2. Class function definitions.
1
Object Oriented Programming through C++
The class declaration describes the type and scope of its members. The class function definition
describes how the class functions are implemented.
An example of a class is
Class ABC
{
private:
int x,y;
public:
void getdata(int a, int b);
void setdata( );
};
The variables of a class is called ‘data members’ and the functions are called ‘member functions’. In the
above example, x and y are the data members and getdata( ) and setdata( ) are the member functions.
The class members that have declared as private can be accessed only from within the class, and public
members can be accessed from outside of the class. By default, the data and functions declared within a class
are private to that class.
There are 3 access specifiers in OOP: private, public and protected( needed in inheritance purposes).
An object has physical existence. An object is an instance of a class. It is an identifiable entity with some
characteristics and behavior. To declare an object first we have to write the class name and then the object
name. Thus an object is created. It can access the entire properties of a class.
For example, ABC ob;
Here ob is the object of class ABC.
Member functions are accessed from the outside of the class by ‘.’ Operator. Such as ob.setdata( ) and
ob.getdata(1, 2).
Encapsulation is a mechanism in which data and functions of a class are binds together to keep protect
from the outside interference or misuse.. It is the most striking feature of a class. When the data and functions
of a class are binds together, then an object is created of that class. The data are not accessed by the outside
world, and only those function which are wrapped in the class can access it. These functions provide the
interface between the object’s data and program. The insulation of the data from direct access by the program
is called data hiding or information hiding.
2
Object Oriented Programming through C++
Abstraction refers to the act of representing essential features without including the background details or
explanations. Classes use the concept of abstraction and are defined as a list of abstract attributes such as size,
weight and cost, and methods that operate on these attributes. They encapsulate all the essential properties of
the objects that are to be created.
Abstract refers to the act of representing essential features without including the background details or
explanations. Classes use the concept of abstraction and are defined as a list of abstract attributes – data
members and member functions.
Since the classes use the concept of data abstraction, they are known as Abstract Data Types(ADT).
Reusability
Once a class has been created and debugged, it can be distributed to other programmers for use in their
own programs. This is called reusability. In OOP, the concept of inheritance provides an important extension
to the idea of reusability. A programmer can take an existing class and then add some additional features and
capabilities to the class without modifying the class. Then the new class then have the combined features of
both the classes.
A const member function guarantees that it will never modify any of its class’s member data
A const member function is declared as
<return type> function_name( parameter _list) const
{
//body of the function
}
When a member function declared as const, then the compiler checks if you have made any change of any
data members of that class. Compiler will generate an error if such functions try to change the data values.
Same meaning can be applied on data members by simply declare the data members like as
‘::’ is a scope-resolution operator. This operator links a class name with a member name. The operator tells
the compiler in what class the member belongs to. A member is defined by the scope resolution operator as
A constructor is used to initiate an object automatically when it is declared. A constructor is called when
an object comes into existence. A constructor is executed when the object declaration statement is
encountered. A constructor is declared as
3
Object Oriented Programming through C++
class name
{
public:
name( )
{
//body of constructor
};
};
[ Note: Constructors of global objects are executed before the execution of the main function].
constructors can be called in any one of two ways:
name ob1=name(100); //explicit call
name ob1(100);//implicit call
A destructor is called when an object is destroyed. A destructor never takes any argument; it does not
return any value. It will be invoked automatically by the complier upon exist from program. A destructor is
declared as:
class name
{
public:
~name()
{
// body of destructor
}
}
Implicit Constructor
This constructor creates objects, even though was not defined in the class. This constructor will not do
anything and is defined just to satisfy the compiler.
class integer
{
Public:
integer( ) { } // implicit integer
}
Properties of constructors
4
Object Oriented Programming through C++
1. A constructor is a member function, which is invoked automatically when an object is created and a
Destructor is a member function, which is invoked when an object is destroyed.
2. A constructor sometimes takes argument. But a destructor never takes any argument.
1. Destructors are used to destroy object that have been created by a constructor.
2. They are used to release the memory space for future use when they are no longer required.
Local Class
The class that is defined within main function or another general function is called local class.
Reference Variables
A reference variable provides an alias for previously defined variables. For example, if we make the
variable sum and a reference to the variable total, then sum and total can be used interchangeably to represent
that variable.
int sum=10;
int &total=sum;
Prototype Declaration
The prototype describes the function to interface to the compiler by giving details such as the
number and type of arguments and the type of return values.
Function prototype is a declaration statement in the calling function. It is declared by writing
the signature of a function followed by a semicolon (;), that is if a signature of a function is
void(int a, float b), then the prototype declaration of that function is
void(int a, float b);
5
Object Oriented Programming through C++
The argument list of the function prototype must be same as the argument list in the function
calling.
#include<iostream.h>
class gamma
{
static int total;
public:
gamma() Output:
{
total ++;
Total is 1
}
~gamma() Total is 3
{ Destroying
total--; Destroying
cout<<"Destroying "<<endl; Destroying
}
static void showtotal()
{
cout<<"Total is
"<<total<<endl;
}
};
6
Object Oriented Programming through C++
Friend Function
Friend function is a nonmember function of any class. Friend functions are used to access
all protected and private members of a class. To declare a friend function the keyword friend is
written followed by the ‘signature of the function’. A Friend function can not be declared within
a class. It is always declared outside of the class without using scope resolution operator. To call
a friend function outside of the class, it doesn’t need the dot operator. Friend function can act as
a bridge between two classes. A friend function can handle the private members of more than
one class.
#include<iostream.h>
class c2; //forward declaration
class c1
{
public:
friend int sum(c1 a, c2 b);
int c;
};
class c2
{
public:
friend int sum(c1 a, c2 b);
int d;
}
int sum(c1 a, c2 b)
{
return( a.c + b.d);
}
void main()
{
c1 ob1; c2 ob2;
ob1.c=10;
ob2.d=20;
cout<<sum(ob1,ob2);
}
7
Object Oriented Programming through C++
This pointer
When the member functions are called then they are automatically passed to an implicit argument
that is a pointer to the invoking object. This pointer is called this pointer.
This pointer is useful to show that the member that it points to is the member of the invoking
object or classes. That is
this->b=base (b=base)
this->b refers to the object’s copy of b.
This pointer is also useful when operators are overloaded and whenever a member functions must
utilize a pointer to the object that invoked it.
Disadvantage of pointers
1. By a base class pointer one cannot access elements of a derived class.
2. A pointer of any class type cannot points to any other objects of any type.
1. New operator automatically allocates enough memory to hold an object of the specified type. We do
not need to use an size of operator. Because the size is automatically computes.
2. New operators automatically return the pointer to the specified type. We don’t need to use an explicit
type cast as you we do while allocating memory with malloc( ).
3. New and delete operators can be overloaded.
4. It is possible to initialize the object while creating the memory space.
Inline functions
An Inline function is a function that is expanded in line when it is invoked. That is, the compiler
replaces the function call with the corresponding function code. To make a function inline add the ‘inline’
keyword before declaring a function.
8
Object Oriented Programming through C++
But there are some restrictions on defining a function to be inline functions. A function declared to be
inline functions must have one or two lines. Inline keywords merely send a request, not a command to the
compiler. The compiler may ignore the request if the inline function has too long lines to compile.
#include<iostream.h>
inline int func(int a)
{
return a*a;
}
void main()
{
cout<<func(5);
}
Inline functions are used to save memory space, which is suitable when a function is to be called many
times. These functions are useful to run a program faster. As ordinary functions it does not require to
saving register, push current status on to stack.
[ Note: In case of a class, if the member functions are declared inside the class then the member functions
are called inline function]
Default arguments
C++ allows us to call a function without specifying all its arguments. In such cases, the function assigns a
default value to the parameter which does not have a matching arguments in the function call. Default
values are specified when the function prototype is declared. The compiler looks at the prototype to see
how many arguments a function uses and alerts the program for possible default values. Here is an
example of a prototype with default values.
float amount( float a, int b, float c=0.0)
The above prototype declares a default value of 0.0 to the argument rate.
A function call like
value=amount(5000,7) passes a=5000, b=7 and c=0.0
If a function call like value=amount(2000, 3, 0.12) then passes a=2000, b=3, c=0.12
One important point is that only the trailing argument can have default values. We must add default
values from right to left that is
int func(int i, int j=10, int k=10) // is legal
9
Object Oriented Programming through C++
#include<iostream.h>
void line(char ch='*', int size=25);
void main()
{
line('=',20);
line('=');
line();
}
Output:
====================
=========================
*************************
1. We can use default arguments to add new parameters to the existing functions.
2. Default arguments can be used to combine similar functions into one.
Like any other data type objects are also passed as an function argument. These can be done in
two ways.
1. Pass-by-value
2. Pass-by-reference
In the first method, a copy of an entire object is passed to a function. Since a copy of the object is
passed to the function any changes made to the object inside the function do not affect the object by
which the function was called.
void item:: getdata(item t1)
{
int count;
t1.a=count++;
}
10
Object Oriented Programming through C++
In the second method, the address of an object is passed to a function. This means that any changes made
to the object inside the function will reflect the actual object. These method is more efficient since it
passed only the address of the object and not the entire object.
Here, the address of the object t1 is passed to the function argument as call-by-reference.
INHERITANCE
I nheritance is the process in which the objects of one class can access the properties of another class.
In Object Oriented Programming, heritance provides the concept of reusability. This means, that we can add
additional features to an existing class without modifying it. This is possible by deriving a new class form the
existing class. Then the existing class called the base class and the new class is called derived or child class.
The new class will have the combined features of both the two classes. A class can also inherits properties
from more than one class or form more than one level. A derived class with only one base class is called
single inheritance and with several base classes is called multiple inheritance.
A derived class can be defined by specifying its relationship with the base class by specifying its
relationship with the base class in additon to its own details. The general form of defining a derived class is:
The visibility-mode can be private, public or protected. This is optional. Default visibility-mode is
private. Visibility-mode specifies whether the features of the base class are privately derived or publicly
derived or protectedly derived.
For example, If XYZ is a base class and ABC is a derived class of XYZ
11
Object Oriented Programming through C++
};
When the base class is privately inherited by a derived class, ‘public’ members of the base class
become ‘private’ members of the derived class, so the public members of the base class can be accessed by
the member functions of the derived class, but they are not accessible by the objects of the derived class.
Protected members of the base class become ‘private’ members of the derived class.
When the base class is publicly inherited by a derived class, ‘public’ members of the base class
become ‘public’ members of the derived class, so they are accessible by the objects of the derived class.
Private members of the base class can not be inherited and they are not accessible by the objects of the
derived classes. ‘Protected’ members of a base class become ‘protected’ members of the derived class.
When the base class is inherited by a derived class as protected , ‘public’ members of the base class
become ‘protected’ members of the derived class, ‘protected’ members of the base class become ‘protected’
members of the derived class and ‘private’ members of the base class are not accessible by the objects of the
derived classes.
For example, as illustrated in this program, objects of type derived can directly access the public
members of base:
#include<iostream.h>
class base
{
int i,j;
public:
void set(int a, int b) {i=a; j=b;}
int main()
{
derived ob(3);
ob.set(1,5); // access member of base
ob.show(); // access member of base
ob.showk(); // uses member of derived class
}
When the base class is inherited by using the private access specifier, all public and protected members of
the base class become private members of the derived class. For example, the following program will not
even complile because both set( ) and show( ) are now private elements of derived.
12
Object Oriented Programming through C++
class base
{
int i,j;
public:
void set(int a, int b) { i=a; j=b; }
int main()
{
derived ob(3);
ob.set(1,2); //error, can't access set()
ob.show();//error, can;t access show()
return 0;
}
The protected keyword is included in C++ to provide greater flexibility in the inheritance mechanism. When
a member of a class is declared as protected, that member is not accessible by other, nonmember elements of
the program. Access to a protected member is the same as access to private member-it can be accessed only
by other members of its class. The sole exception to this is when a protected member is inherited. In this case,
a protected member differs substantially from a private one.
By using protected, one can create class members that are private to their class but that can still be
inherited and accessed by a derived class. Here is an example:
#include<iostream.h>
class base
{
protected:
int i,j; // private to base, but accessible by derived
public:
void set(int a, int b) { i=a; j=b;}
void show() { cout<<i<<" "<<j<<"\n";}
};
13
Object Oriented Programming through C++
int k;
public:
//derived may access base's i and j
void setk() { k=i*j;}
void showk() { cout<<k<<"\n";}
};
int main(void)
{
derived ob;
ob.set(2,3); //OK, known to derived
ob.show(); //OK, known to derived
ob.setk();
ob.showk();
return 0;
}
In this example, because base is inherited by derived as public, and because i and j are declared as
protected, derived’s function setk() may access them. If I and j had been declared as private by base, then
derived would not have access to them, and the program would not compile .
When a derived class is used as a base class for another derived class, any protected member of
the initial base class that is inherited(as public) by the first derived class may also be inherited as
protected again by a second derived class. For example, this program is correct, and derived2
does indeed have access to i and j.
#include<iostream.h>
class base
{
protected:
int i,j;
public:
void set(int a, int b) { i=a; j=b;}
void show() { cout<<i<<" "<<j<<"\n";}
};
14
Object Oriented Programming through C++
int main(void)
{
derived1 ob1; derived2 ob2;
ob1.set(2,3); ob1.show();
ob1.setk(); ob1.showk();
ob2.set(3,4); ob2.show();
ob2.setk(); ob2.showk();
ob2.setm(); ob2.showm();
}
It is possible to inherit a base class as protected. When this is done, all public and protected members of
the base class become protected members of the derived class. For example,
#include<iostream.h>
class base
{
protected:
int i,j;//private to base, but accessible by derived
public:
void setij(int a, int b) { i=a, j=b;}
void showij() { cout<<i<<" "<<j<<"\n";}
};
int main(void)
{
derived ob;
//ob.setij(2,3) // illegal, setij() is protected member of derived
ob.setk(); //OK, public member of derived
15
Object Oriented Programming through C++
class base1
{
protected:
int x;
public:
void showx() { cout<<x<<"\n"; }
};
class base2
{
protected:
int y;
public:
void showy() { cout<<y<<"\n";}
};
int main(void)
{
derived ob;
ob.set(10,20);//provided by derived
ob.showx(); ob.showy();
}
Constructors & Destructors in Inheritance
When an object of a derived class is created, then first the base’s constructor is called and then the
derived’s constructor is called. When that object is destroyed, then first the derived’s destructor is called
and then the base’s destructor is called. That means, constructors are executed in their order of derivation.
Destructors are executed in reverse order of derivation .
#include<iostream.h>
class base
{
public:
base() { cout<<"Constructing base\n"; }
16
Object Oriented Programming through C++
int main(void)
{
derived ob;
return 0;
}
Output:
Constructing base
Constructing derived
Destructing derived
Destructing base
Why protected access specifiers are used in Inheritance?
We know that private member functions of a base class cannot be inherited by the derived class,
therefore they are not accessed by the member functions of the derived class. But if we need to inherit the
private members of the base class, then we must inherit the base class protectedly. These modify the
visibility limit of the private member by making it public. A member declared as protected is accessible
by the member functions within its class and any class that are derived from it. It cannot be accessed by
the functions outside of these two classes. When a protected member is inherited in public mode then it
becomes protected, so it can accessed by the member functions of the derived class. When a protected
member is inherited in private mode then it becomes private in the derived class.
When a base class is inherited by its derived class in protected mode then the public and protected
members of base class becomes protected members of derived class, and the private members of the base
class cannot accessible by the derived class.
To inherit a base class in protected mode we declare:
class D: protected B
{
// body of the class
};
In what order are the class constructors called when a derived class object is created?
When a derived class object is created then the class constructors are called in the order in which they
appear in the declaration of the derived class. When a object of a derived class is created then first the
constructors in the base class are called and then the constructors in the derived class are called. The
17
Object Oriented Programming through C++
constructor of the derived class receives the entire list of values as its arguments and passes them on to
the base constructors in order in which they are declared in the derived class.
The derived class constructor contains two parts separated by a colon(:). The first part contains the
declaration of the arguments that are passed to derived constructor and the second part contains the
initialization of the objects of the base class and derived class.
Here is a simple program
class alpha
{
int a;
public:
alpha(int m){ a=m; }
void showa() {cout<<a; }
};
int main(void)
{
beta ob(5,10);
ob.showa();
ob.showb();
return 0;
}
We pass arguments to a constructor on a base class, with the help of the derived class that inherits the
base class. A derived class constructor takes all arguments of its own and the arguments of the base class
constructor. And then pass these arguments to one or more base-class constructor. The general form of this
expanded derived class constructor is shown here:-
#include<iostream.h>
class base
{
protected:
int i;
18
Object Oriented Programming through C++
public:
base(int x) { i=x; cout<<"Constructing base\n";}
~base( ) { cout<< "Destructing base\n";}
};
int main()
{
derived ob(3,4);
ob.show(); //displays 4 3
return 0;
}
Output :
Constructing base
Constructing derived
4 3
Destructing derived
Destructing base
Here, derived’s constructor is declared as taking two parameters, x and y. However, derived( ) uses only x; y
is passed along to base( ). In general, the derived class’ constructor must declare both the parameters that it
requires as well as any required by the base class.
#include<iostream.h>
class base1
{
protected:
int i;
public:
base1(int x) { i=x; cout<<"Constructing base1\n";}
~base1( ) { cout<< "Destructing base1\n";}
};
class base2
{
protected:
int k;
public:
base2(int x) { k=x; cout<<"Constructing base2\n";}
~base2( ) { cout<< "Destructing base2\n";}
19
Object Oriented Programming through C++
};
int main()
{
derived ob(3,4,5);
ob.show(); //displays 4 3 5
return 0;
}
Output :
Constructing base1
Constructing base2
Constructing derived
4 3 5
Destructing derived
Destructing base2
Destructing base1
It is important to understand that arguments to a base-class constructor are passed via arguments to
the derived class’ constructor. Therefore, even if a derived class’ constructor does not use any arguments, it
will still need to declare one if the base class requires it. In this situation, the arguments to the derived class
are simply passed along to the base. For example, in this program, the derived class’ constructor takes no
arguments, but base1( ) and base2( ) do.
#include<iostream.h>
class base1
{
protected:
int i;
public:
base1(int x) { i=x; cout<<"Constructing base1\n";}
~base1( ) { cout<< "Destructing base1\n";}
};
class base2
{
protected:
int k;
public:
base2(int x) { k=x; cout<<"Constructing base2\n";}
~base2( ) { cout<< "Destructing base2\n";}
};
20
Object Oriented Programming through C++
int main()
{
derived ob(3,4);
ob.show(); //displays 3 4
return 0;
}
Output:
Constructing base1
Constructing base2
Constructing derived
3 4
Destructing derived
Destructing base2
Destructing base1
Polymorphism
OOP languages support polymorphism, which is characterized by the phrase “one interface,
multiple methods”. Polymorphism is the attribute that allows one interface to control access to a general class
of actions. The specific action selected is determined by the exact nature of a situation. Polymorphism helps
reduce complexity by allowing the same interface to be used to access a general class of actions.
Polymorphism
Function Operator
Overloading Overloading Virtual
Function
When the appropriate member function could be selected while the program is running, is known as run
time polymorphism. C++ supports virtual functions to achieve runtime polymorphism.
21
Object Oriented Programming through C++
At run time, when it is known what class objects are under consideration, then the appropriate
version of the function is invoked. Since, the function is linked with a particular class much later after the
compilation, this process is called late binding. It is also known as dynamic binding because the selection
of the appropriate function is done dynamically at runtime.
Function Overloading
Function Overloading is the process of using the same name for two or more functions. The secret
to overloading is that each redefinition of the function must use either different types of parameters or
a different number of parameters. It is only through these differences that the compiler knows which
function to call in any given situation. For example, this program overloads myfunc( ) by using
different types of parameters
#include<iostream.h>
int myfunc(int i); Here, in the main program
double myfunc(double i); when the function
int main() myfunc(10 is called then the
{ compiler invokes
cout<<myfunc(10);//calls myfunc(int i) automatically the function
cout<<myfunc(5.4); //calls myfunc(double i) int myfunc(int i), because 10
return 0;
}
is a integer type argument
and the parameter in the
double myfunc(double i) function definition is also an
{ integer type.
return i;
}
int myfunc(int i)
{
return i;
}
22
Object Oriented Programming through C++
Function Overriding is the mechanism of having the same member function in both the base class and
derived classes. In this case, the function in the derived class overrides on the function of the base
class.
#include<iostream.h>
class Base
{ Output:
public: Derived class
void show()
{ In this case, the base class and
cout<<"Base class"; the derived class both contains
} the same member functions
}; void show( ). In the main
function an object is created of
class Derv : public Base the type Derv. Then the
{
public:
member function show( ) is
void show() called by the object d1. In this
{ case, the compiler invoked the
cout<<"Derived class"; function of derived class. If we
} want to call the show( )
}; function of base class then we
have to write.
int main(void)
{ D1.Base::show();
Derv d1;
d1.show();return 0;
}
Copy constructor
A copy constructor is a constructor that creates a new object and copies its argument into it. The
default copy constructor which is provided automatically by the compiler for every object, perform a
member-by-member copy. This is similar to what the assignment operator does; the difference is that the copy
constructor also creates a new object.
23
Object Oriented Programming through C++
#include<iostream.h>
class alpha
{
private:
int data;
public:
alpha()
{
}
alpha(int d)
{
data=d;
}
alpha(alpha &a)
{
data=a.data;
cout<<"\n Copy constructor invoked";
}
void display()
{
cout<<data;
}
void operator=(alpha &a)
{
data=a.data;
cout<<"Assignment operator invoked";
}
};
int main(void)
{
alpha a1(37);
alpha a2;
a2=a1; //invoke = operator
cout<<"\n a2= "; a2.display();
alpha a3(a1); // invoke copy constructor
a3.display();
}
If we use alpha (alpha a), then the compiler complains that is out of memory. Because when an argument is
passed by value, a copy of it is constructor. But this is the copy constructor, so it calls itself. In fact, it calls
itself over and over until the complier runs out of memory. So, in the copy constructor, the argument must be
passed by reference, which creates no copy.
Copy constructor is called every time a copy of an object is made. When you pass an object by value,
either into a function or as a function's return value, a temporary copy of that object is made.
Assignment operator is called whenever you assign to an object. Assignment operator must check to see if the
right-hand side of theassignment operator is the object itself. It executes only the two sides are not equal.
24
Object Oriented Programming through C++
Operator Overloading
C++ has the ability to provide the operators with a special meaning for a data type. The mechanism
of giving such special meanings to an operator is known as operator overloading. 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 special function, called operator function. The operator function defines the
operations performed by the overloaded operator relative to the class upon which it will work.
The # is a placeholder. When a operator functions is to be created substitute the operator for the #. For
example, if you overloading the ‘ /’ operator, then use operator ‘/’. When you are overloading a unary
operator, arg_list will be empty. When you are overloading binary operators, arg_list will contain one
parameter.
Here is an example of operator overloading. This program creates a class called counter which stores
the count value. It overloads the ++ operator relative to this class.
// overloading unary operator
#include<iostream.h>
class counter
{
private:
int count;
public:
counter(): count(0)
{ }
counter(int c): count (c)
{ }
void display()
{
cout<<count<<"\n";
}
void operator ++()
{
++count;
}
};
int main(void)
{
counter c1(10);
++c1; ++c1; // prefix operators
c1.display(); return 0;
}
In this program, an object c1 of class type counter is created, we increment c1 twice and then displaying the
resulting value.
25
Object Oriented Programming through C++
Then the ++ operator is treated as postfix operators and then we have to write the expression c1++ instead of
++c1.
Here is an another example of operator overloading which overload binary operator ‘+’.
#include<iostream.h>
class sum
{
int data;
public:
sum()
{
data=0;
}
sum(int a)
{
data=a;
}
void display()
{
cout<<data;
}
sum operator + (sum s2)
{
sum temp;
temp.data=s2.data+data;
return temp;
}
};
int main(void)
{
sum ob1(5), ob2(8);
ob1=ob1+ob2;
ob1.display(); // displays 13
return 0;
}
In this program two objects are created. Then we add the two object using ‘+’ operator then assigns
the result to the ob1.
Disadvantages
1. We can not alter the precedence of an operator.
2. We cannot change the no. of operands that an operator takes.
3. Operator function cannot have default arguments.
4. . :: ? operators cannot be overloaded.
26
Object Oriented Programming through C++
[ Note: A friend function will have only one argument for unary operation and two for binary operation,
where as a member function has no argument for unary operation and one operator for binary operations]
#include<iostream.h>
class loc
{
int longitude, latitude;
public:
loc() { }
loc( int lg, int lt)
{
longitude=lg;
latitude=lt;
}
void show()
{
cout<<longitude<<" ";
cout<<latitude<<"\n";
}
loc operator+(loc op2);
loc operator -(loc op2);
loc operator =(loc op2);
loc operator++();
};
//overload + for loc
loc loc :: operator +(loc op2)
{
loc temp;
temp.longitude=op2.longitude+longitude;
temp.latitude=op2.latitude+latitude;
return temp;
}
//overload ++ operator
loc loc :: operator ++()
{
longitude++;
27
Object Oriented Programming through C++
latitude++;
return *this;
}
int main(void)
{
loc ob1(10, 20), ob2(5, 30), ob3(90,90);
++ob1;
ob1.show(); //displays 11 21
ob2=++ob1;
ob1.show(); //displays 12 22
ob2.show(); //displays 12 22
ob1=ob2=ob3; //multiple assignment
ob1.show(); //displays 90 90
ob2.show(); //displays 90 90
return 0;
}
int main(void)
{
string s1="object";
string s2=" oriented";
string s3;
s3=s1+s2; // s1=s1+s2; or s1+s2
s3.show(); // s1.show();
28
Object Oriented Programming through C++
return 0;
}
int main(void)
{
string s1="abc";
string s2="abcd";
string s3="abc";
if( s1< s2)
cout<<"s2 is larger";
else
cout<<"s1 is larger";
if(s1=s3)
cout<<"strings are equal";
else
cout<<"strings are not equal`";
return 0;
}
29
Object Oriented Programming through C++
#include<iostream.h>
class Distance
{
int feet;
float inches;
public:
Distance()
{
feet=0;
inches=0.0;
}
One can overload an operator for a class by using nonmember function, which is usually a friend of
the class. Since, a friend function is not a member of the class, it does not have a this pointer. Therefore, an
overloaded friend operator function is passes the operands explicitly. This means that a friend function that
overloads a binary operator has two parameters, and a friend function that overloads a unary operator has one
parameter. When overloading a binary operator using a friend function, the left operand is passed in the first
parameter and the right operand is passed in the second parameter.
In this program, the operator+ ( ) function is made into a friend.
30
Object Oriented Programming through C++
#include<iostream.h>
class loc
{
int longitude, latitude;
public:
loc() { }
loc( int lg, int lt)
{
longitude=lg;
latitude=lt;
}
void show()
{
cout<<longitude<<" ";
cout<<latitude<<"\n";
}
friend loc operator+(loc op1, loc op2); // now a friend
};
Assume some class that defines a member operator+( ) function that adds an object of the class to an integer.
Given an object of that class called Ob, the following expression is valid:
Ob + 100 //valid
In this case, Ob generates the call to the overloaded + function, and the addition is performed. But what
happens if the expression is written like this?
100 + Ob // invalid
In this case, it is an integer that appears on the left. Since an integer is a built-in type, no operation
between an integer and an object of Ob’s type is defined. Therefore, the compiler will not compile this
31
Object Oriented Programming through C++
expression. The solution to the preceding problem is to overload addition using a friend, not a member
function. When this is done, both arguments are explicitly passed to the operator function. Therefore, to allow
both object +integer and integer +object, simply overload the function twice-one version for each situation.
Thus, when you overload an operator by using two friend functions, the object may appear on either the left
or right side of the operator.
This program illustrates how friend functions are used to define an operation that involves an object
and built-in type:
#include<iostream.h>
class number
{
int num;
public:
number()
{ }
number(int a)
{
num=a;
}
void show()
{
cout<<"Value is " <<num<<endl;
}
friend number operator+ (number ob, int val);
friend number operator+ (int val, number ob);
};
int main(void)
{
number ob1(5), ob2(10), ob3, ob4;
ob3=ob1+14;
ob4=20+ob2;
ob1.show(); // displays 5
ob2.show(); // displays 10
ob3.show(); // displays 19
ob4.show(); // displays 30
32
Object Oriented Programming through C++
return 0;
}
Virtual Functions
A virtual function is a member function that is declared within a base class and redefined by a derived
class. To create a virtual function, precede the function’s declaration in the base class with the keyword
virtual. When a class containing a virtual function is inherited, the derived class redefines the virtual function
to fit its own needs. In essence, virtual functions implement the “one interface, multiple methods” philosophy
that underlies polymorphism. The virtual within the base defines the form of the interface to that function.
Each redefinition of the virtual function by a derived class implements its operation as it relates specifically to
the derived class. That is, the redefinition creates a specific method.
A base-class pointer can be used to point to an object of any class derived from the base. When a base
pointer to a derived object that contains a virtual function, C++ determines which version of that function to
call based upon the type of object pointed to by the pointer. And this determination is made at runtime. Thus,
when different objects are pointed to, different versions of the virtual function are executed.
#include<iostream.h>
class base
{
public:
virtual void vfunc( ){
cout<<"This is base's vfunc()\n";
}
};
int main(void)
{
base *p ,b;
derived1 d1;
derived2 d2;
// point to base
p=&b;
p->vfunc( ); //access base's vfunc()
// point to derived1
p=&d1;
p->vfunc( ); //access derived1's vfunc()
33
Object Oriented Programming through C++
// point to derived2
p=&d2;
p->vfunc( ); //access derived2's vfunc()
Output:
This is base's vfunc()
This is derived1's vfunc()
This is derived2's vfunc()
As the program illustrates, inside base, the virtual function vfunc( ) is declared. Notice that the
keyword virtual precedes the rest of the function declaration. When vfunc( ) is redefined by derived1 and
derived2, the keyword virtual is not needed.
In this program, base is inherited by both derived1 and derived2. Inside each class definition, vfunc(
) is redefined relative to that class. Inside main( ), four variables are declared:
Next, p is assigned the address of b, and vfunc( ) is called via p. Since p is pointing to an object of
type base, that version of vfunc( ) is executed. Next, p is set to the address of d1, and again vfunc( ) is called
by using p. This time p points to an object of type derived1. This causes derived1’s vfunc( ) to be executed.
Finally, p is assigned the address of d2, and p->vfunc( ) causes the version of vfunc( ) redefined inside
derived2 to be executed. The key point here is that the kind of object to which p points determines which
version of vfunc( ) is executed. Further, this determination is made at run time, and this process forms the
basis for run-time polymorphism.
However, this is not the case, and the term overloading is not applied to virtual function redefinition
because several differences exist. Perhaps the most important is that the prototype for a redefined virtual
function must match exactly the prototype specified in the base class. This differs from overloading a normal
function, in which return types and the member and type of parameters may differ. Another important
restriction is that virtual functions must be nonstatic members of the classes of which they are part. They
cannot be friends.
When a virtual function is inherited, its virtual nature is also inherited. This means that when a derived
class that has inherited a virtual function is itself used as a base class for another derived class, the virtual
function can still be overridden. Put differently, no matter how many times a virtual function is inherited,
it remains virtual. For example, consider this program:
#include<iostream.h>
class base
{
public:
virtual void vfunc( ){
cout<<"This is base's vfunc()\n";
}
};
34
Object Oriented Programming through C++
int main(void)
{
base *p ,b;
derived1 d1;
derived2 d2;
// point to base
p=&b;
p->vfunc( ); //access base's vfunc()
// point to derived1
p=&d1;
p->vfunc( ); //access derived1's vfunc()
// point to derived2
p=&d2;
p->vfunc( ); //access derived2's vfunc()
When a function is declared as virtual by a base class, a derived class may override it.
However, the function does not have to be overridden. When a derived class fails to override a
virtual function, then when an object of that derived class accesses that function, the function
defined by the base class is used. For example, consider this program in which derived2 does not
override vfunc( ):
#include<iostream.h>
class base
{
public:
virtual void vfunc( )
{
cout<<"This is base's vfunc()\n";
}
};
35
Object Oriented Programming through C++
{
public:
void vfunc( )
{
cout<<"This is derived1's vfunc()\n";
}
};
int main(void)
{
base *p ,b;
derived1 d1;
derived2 d2;
// point to base
p=&b;
p->vfunc( ); //access base's vfunc()
// point to derived1
p=&d1;
p->vfunc( ); //access derived1's vfunc()
// point to derived2
p=&d2;
p->vfunc( ); //access derived2's vfunc()
Output:
This is base's vfunc()
This is derived1's vfunc()
This is base's vfunc()
Because derived2 does not override vfunc( ), the function defined by base is used when vfunc( ) is
referenced relative to objects of type derived2.
When a virtual function is not redefined by a derived class, the version defined in the base class will
be used. However, in many situations there can be no meaningful definition of a virtual function
within in a base class. For example, a base class may be not be able to define an object sufficiently to
allow a base-class virtual function to be created. Further, in some situations you will want to ensure
that all derived classes override a virtual function. To handle, these two cases, C++ supports the pure
virtual function.
36
Object Oriented Programming through C++
A pure virtual function is a virtual function that has no definition within the base class. To
declare a pure virtual function, we use the general form:
When a virtual function is made pure, any derived class must provide its own definition. If
the derived class fails to override the pure virtual function, a compile-time error will result.
#include<iostream.h>
class area
{
protected:
int x, y;
public:
area(int a, int b=1)
{
x=a, y=b;
}
void show()
{
cout<<"Area of rectangle is "<<x*y<<"\n";
}
};
void show()
{
cout<<"Area of square is "<<x*x<<"\n";
}
};
int main(void)
{
rectangle r1(3,8);square s1(5);
r1.show();
s1.show();
return 0;
}
Output:
Area of rectangle is 24
37
Object Oriented Programming through C++
Area of square is 25
Here the base class area, contains x and y, the constructor and a pure virtual function show( ). The derived classes
rectangle and square inherit x and y and redefine show() to fit its own needs.
Virtual Destructor
Base class destructor should always be virtual. Suppose you use delete with a base class pointer to a
derived class object to destroy the derived-class object. If the base-class destructor is not virtual then delete,
like a normal member function, calls the destructor for the base class, not the destructor of the derived class.
This will cause only the base part of the object to be destroyed.
#include< iostream.h>
class Base
{
public:
~Base( ) // non-virtual destructor
// Virtual ~Base( ) // virtual destructor
{
cout<<”Base Destroyed\n”;
}
};
class Derv : public Base
{
public:
~Derv( )
{
cout<<”Derv Destroyed\n”;
}
};
int main()
{
Base *pBase=new Derv; delete pBase;
}
Abstract Classes
A class that contains at least one pure virtual function is said to be abstract. Because an abstract class
contains one or more functions for which there is no definition (that is, pure virtual function), no objects of an
abstract class may be created. But, we can create pointers to an abstract class. This allows abstract classes to
support the run-time polymorphism.
An element of ambiguity can be introduced into a C++ program when multiple base classes are
inherited. For example, consider this incorrect program:-
38
Object Oriented Programming through C++
/* derived3 inherits both derived1 and derived2. This means that there are two
copies of base in derived3!*/
class derived3 : public derived1, public derived2
{
public:
int sum;
};
int main()
{
derived3 ob;
ob.i=10; // This is ambiguous, which i???
ob.j=20;
ob.k=30;
// i is ambiguous, too
ob.sum=ob.i+ob.j+ob.k;
As the comments in the program indicate, both derived1 and derived2 inherit base. However, derived3
inherits both derived1 and derived2. This means that there are two copies of base present in an object of type
derived3. Therefore, in an expression like ob.i = 10;
Which i is being referred to, the one in derived1 or the one in derived2? Because there are two
copies of base present in object ob, there are two ob.i! So, the statement is ambiguous.
So, there is a problem. And there is a solution of the above problem. When two or more objects are
derived from a common base class, we can prevent multiple copies of the base class by declaring the base
class as virtual when it is inherited. You accomplish this by preceding the base class’ name with the keyword
virtual when it is inherited. ( For example, here is another version of the example program in which derived3
contains only one copy of base:
39
Object Oriented Programming through C++
public:
int i;
};
public:
int sum;
};
int main()
{
derived3 ob;
ob.i=10; // now unambiguous
ob.j=20;
ob.k=30;
// unambiguous
ob.sum=ob.i+ob.j+ob.k;
// unambiguous
cout<<ob.i<<" "<<ob.j<<" "<<ob.k<<" "<<ob.sum<<"\n";
}
Now, that both derived1 and derived2 have inherited base as virtual, any multiple inheritance involving
them will cause only one copy of base to be present. Therefore, in derived3 there is only one copy of
base and
ob.i = 10 is perfectly valid and unambiguous and in this case this base class is called ‘virtual base class’.
40
Object Oriented Programming through C++
Early Binding refers to events that occur at compile time. In essence, early binding occurs when all
information needed to call a function is known at compile time. Examples of early binding include normal
function calls(including standard library functions), overloaded function calls, and overloaded operators. The
main advantage to early binding is efficiency. Because all information necessary to call a function is
determined at compile time, these types of function calls are very fast.
The opposite of early binding is late binding. As it relates to C++, late binding refers to function calls
that are not resolved until runtime. Virtual functions are used to achieve late binding. When an object is
accessed via a base pointer or reference, the virtual function actually called is determined by the type of
object pointed to by the pointer. Because in most cases this cannot be determined at compile time, the objects
and the functions are not linked until run time. The main advantage to late binding is flexibility. Late binding
can make slower execution times because a function call is not resolved until runtime.
Templates
A generic function or a template function defines a general set of operations that will be applied to various
types of data. The type of data that the function will operate upon is passed to it as a parameter. A single
general procedure can be applied to a wide range of data. By using generic functions we can apply sorting
algorithm to an array of integers or an array of floats.
A generic function is created using the keyword template. The general form of a template function
definition is shown here:
Here, Ttype is a placeholder name for a data type used by the function. It is only a placeholder that the
compiler will automatically replace with an actual data type when it creates a specific version of the function.
The following example creates a generic function that swaps the values of the two variables with
which it is called. The general process of exchanging two values is independent on the type of the variables.
#include<iostream.h>
int main(void)
{
int i=50, j=100;
double x=10.5, y=14.8;
char a='c', b='d';
41
Object Oriented Programming through C++
Output:
Original i, j: 50 100
Original x, y: 10.5 14.8
Original a, b: c d
Swapped i, j: 100 50
Swapped x, y: 14.8 10.5
Swapped a, b: d c
You can define more than one generic data type in the template statement by using a comma-
separated list. For example, this program creates a template function that has two generic types:
#include<iostream.h>
template <class type1, class type2> void func(type1 x, type2 y)
{
cout<<x<<" "<<y<<"\n";
}
42
Object Oriented Programming through C++
int main()
{
func(10, "I like C++");
func(14.56, 100L);
func('A', 67);
return 0;
}
In the above example, the placeholder types type1 and type2 are replaced by the compiler with the data types
int and char*, and double and long, and char and char*, respectively, when the complier generates the
specific instances of func() within main().
Even though a generic function overloads itself as needed, you can explicitly overload one, too. If
you overload a generic function, that overloaded function overrides the generic function relative to that
specific version. For example, consider the following program.
#include<iostream.h>
template<class X> void myfunc(X a)
{
cout<<"Inside template function "<<a<<"\n";
void myfunc(int a)
{
cout<<"Inside overloaded function "<<a<<"\n";
}
int main(void)
{
myfunc(10.84); myfunc(12L);
myfunc(50);
myfunc("C++ Programming");
return 0;
}
Output:
As the comments inside the program indicates, when myfunc(10.84) is called, the compiler invokes the
template function but when myfunc(50) is called, the complier invokes the explicitly overloaded version of
myfunc() defined in the program. Thus, the compiler does not generate this version of the generic myfunc()
function, because the generic function is overridden by the explicit overloading.
43
Object Oriented Programming through C++
We can overload a template function. To do so, simply create another version of the template that differs from
any others in its parameter list. For example,
int main(void)
{
func(10);
func(10, 20);
return 0;
}
Generic Classes
Like generic classes, we can create generic classes. The generic classes define the actual data type used by
that class. Those actual data types that will be manipulated by the class is specified as a parameter when
objects of that class are created. The compiler will automatically generate the correct type of object; based
upon the type you specify when the object is created.
The general from of a generic class declaration is shown here:
Here, type is the placeholder type name, which will be specified when a class is instantiated. If necessary, you
can define more than one generic data type using a comma-separated list.
Once you have created a generic class, you create a specific instance of that class using the following
general form:
class_name<type> ob;
Here, type is the type name of the data that the class will be operating upon. The following program is an
example of a generic class.
44
Object Oriented Programming through C++
int main(void)
{
myclass<int, double> ob1(10, 23.50);
myclass<char, char*> ob2('A', "Generic Class");
ob1.show(); ob2.show();
return 0;
}
------------------------------------------------------E N D-----------------------------------------------------------
45