Ds Oops Unit 1
Ds Oops Unit 1
Ds Oops Unit 1
REGULATION 2013
OBJECTIVES:
To comprehend the fundamentals of object oriented programming,
particularly in C++.
To use object oriented programming to implement data structures.
To introduce linear, non-linear data structures and their applications.
UNIT I DATA ABSTRACTION & OVERLOADING
Overview of C++ Structures Class Scope and Accessing Class Members Reference Variables
Initialization Constructors Destructors Member Functions and Classes Friend Function
Dynamic Memory Allocation Static Class Members Container Classes and Integrators
Proxy Classes Overloading: Function overloading and Operator Overloading.
TOTAL: 45 PERIODS
TEXT BOOKS:
1. Deitel and Deitel, C++, How To Program, Fifth Edition, Pearson Education, 2005.
2. Mark Allen Weiss, Data Structures and Algorithm Analysis in C++,Third Edition, Addison-Wesley,
2007.
REFERENCES:
1. Bhushan Trivedi, Programming with ANSI C++, A Step-By-Step approach, Oxford
University Press, 2010.
2. Goodrich, Michael T., Roberto Tamassia, David Mount, Data Structures and Algorithms in C+
+, 7th Edition, Wiley. 2004.
3. Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein, "Introduction
to Algorithms", Second Edition, Mc Graw Hill, 2002.
1
2
UNIT I DATA ABSTRACTION & OVERLOADING
Main program
Function-4 Function-5
The history of C++ begins with C. The reason for this is easy to understand:
C++ is built upon the foundation of C. Thus, C++ is a superset of C. C++ expanded
and enhanced the C language to support object-oriented programming (which is
described later in this module). C++ also added several other improvements to the
C language, including an extended set of library routines. However, much of the
spirit and flavor of C++ is directly inherited from C.
C++ was invented by Bjarne Stroustrup in 1979, at Bell Laboratories in
Murray Hill, New Jersey. He initially called the new language C with Classes.
3
However, in 1983 the name was changed to C++. Stroustrup built C++ on the
foundation of C, including all of Cs features, attributes, and benefits. Most of the
features that Stroustrup added to C were designed to support object-oriented
programming. C++ is the object-oriented version of C.
The Evolution of C++
Since C++ was first invented, it has undergone three major revisions, with
each revision adding to and altering the language. The first revision was in 1985
and the second in 1990. The third occurred during the C++ standardization process.
Toward that end, a joint ANSI (American National Standards Institute) and ISO
(International Standards Organization) standardization committee was formed. The
first draft of the proposed standard was created on January 25, 1994. The final draft
was passed out of committee on November 14, 1997, and an ANSI/ISO standard for
C++ became a reality in 1998. This is the specification for C++ that is usually
referred to as Standard C++.
Progress Check
4
being data controlling access to code. In an object-oriented language, you define
the data and the routines that are permitted to act on that data. Thus, a data type
defines precisely what sort of operations can be applied to that data. To support the
principles of object-oriented programming, all OOP languages, including C++, have
three traits in common: encapsulation, polymorphism, and inheritance.
data data
Function Function
s s
data
Function
s
Data encapsulation.
Data hiding and access mechanisms.
Automatic initialization and clear up of objects.
Operator overloading.
Features required for object oriented language
5
Data encapsulation.
Data hiding and access mechanisms.
Automatic initialization and clear up of objects.
Operator overloading.
Inheritance.
Dynamic binding.
Languages that support OOPS concepts
Real-time systems.
Simulation and modeling.
Object-oriented databases.
AI and expert systems.
Features of OOPS.
Objects.
Classes.
Data abstraction and Encapsulation.
Inheritance.
Polymorphism.
Dynamic binding.
Message passing.
In OOP concepts, all the functions are written in the classes and then we
move to the main program. This approach is called as Bottom-up approach.
6
Objects
PRIVATE
DATA
NO ENTRY
FUNCTIONS
TO PRIVATE
PUBLIC
DATA
ENTRY ALLOWED
FUNCTIONS
TO PUBLIC AREA
7
Fig : 1.3 STRUCTURE OF CLASS
The entire set of data and code of an object can be made a user-defined data
type with the help of a class. Once a class has been defined, we can create any
number of objects belonging to the classes.
Classes are user-defined data types and behave like built-in types of the
programming language.
For example mango, apple and orange are members of the class fruit
Encapsulation
Data abstraction
The insulation of data from direct access by the program is called as data
hiding or information binding.
The data is not accessible to the outside world and only those functions,
which are wrapped in the class, can access it.
Classes use the concept of abstraction and are defined as a list of abstract
attributes such as size, weight, and cost and uses functions to operate on these
attributes.
The attributes are sometimes called as data members because they hold
information. The functions that operate on these data are called as methods or
member functions.
8
Binding refers to the linking of a procedure to the code to be executed in
response to the call. Dynamic binding means that the code associated with a
given procedure call is not known until the time of the call at the run-time.
Classes are known as abstract data types since classes use the
concept of data abstraction.
Inheritance
Inheritance is the process by which one object can acquire the properties
of another object. This is important because it supports the concept of
hierarchical classification. Without the use of hierarchies, each object would have to
explicitly define all of its characteristics. Using inheritance, an object need only
define those qualities that make it unique within its class. It can inherit its general
attributes from its parent. Thus, it is the inheritance mechanism that makes it
possible for one object to be a specific instance of a more general case.
ANIMALS
A message comprises the name of the object, name of the function and the
information to be sent to the object as shown in figure 1.5.
Student.marks(rollno)
9
Fig.1.5 Message structure
An object oriented program consists of a set of objects that communicate
with each other.
Objects communicate with one another by sending and receiving information.
The process of programming in an object oriented languages involves the following
steps:
Abstract Classes
An abstract class is a class (with atleast one virtual function) can be used as a
framework upon which new classes can be built to provide new functionality. A
framework is a combination of class libraries (set of cooperative classes) with
predefined flow of control. It can be a set of reusable abstract classes and the
programmer can extend them. For instance, abstract classes can be easily tuned to
develop graphical editors for different domains like artistic drawing and music
composition. Abstract classes with virtual function can be used as an aid to
debugging.
10
A First Simple Program
Now it is time to begin programming. Lets start by compiling and running the
short sample C++ program shown here:
/*
This is a simple C++ program.
Call this file Sample.cpp.
*/
#include <iostream.h>
using namespace std;
// A C++ program begins at main().
int main()
{
cout << "C++ is power programming.";
return 0;
}
Although Sample.cpp is quite short, it includes several key features that are
common to all C++ programs. Lets closely examine each part of the program.
The program begins with the lines
/*
This is a simple C++ program.
Call this file Sample.cpp.
*/
This is a comment. Like most other programming languages, C++ lets us
enter a remark into a programs source code. The contents of a comment are
ignored by the compiler. The purpose of a comment is to describe or explain the
operation of a program to anyone reading its source code. In the case of this
comment, it identifies the program. In more complex programs, we will use
comments to help explain what each feature of the program is for and how it goes
about doing its work.
In C++, there are two types of comments. The one youve just seen is called
a multiline comment. This type of comment begins with a /* (a slash followed by an
asterisk). It ends only when a */ is encountered. Anything between these two
11
comment symbols is completely ignored by the compiler. Multiline comments may
be one or more lines long.
The next line of code looks like this:
#include <iostream.h>
The C++ language defines several headers, which contain information that is
either necessary or useful to your program. This program requires the header
iostream, which supports the C++ I/O system. This header is provided with your
compiler. A header is included in your program using the #include directive.
DEMERITS OF OOPS
Compiler overhead
Runtime overhead
Introduction to C++
CLASSES
class class_name
{
access_specifier_1:
member1;
access_specifier_2:
member2;
...
} object_names;
Where class name is a valid identifier for the class, object names is an optional
list of names for objects of this class. The body of the declaration can contain
12
members that can be either data or function declarations, or optionally access
specifiers.
Example:
class student
{
public:
long int regno;
char name[15];
void getdata();
void putdata()
{
cout<<regno<<name;
}
}
ACCESS SPECIFIERS
All is very similar to the declaration on data structures, except that we can
now include also functions and members, but also this new thing called access
specifier. An access specifier is one of the following three keywords: private, public
or protected. These specifiers modify the access rights that the members following
them acquire:
Private members of a class are accessible only from within other
members of the same class or from their friends.
Protected members are accessible from members of their same class
and from their friends, but also from members of their derived classes.
Finally, public members are accessible from anywhere where the object
is visible.
By default, all members of a class declared with the class keyword have
private access for all its members. Therefore, any member that is declared before
one other class specifier automatically has private access. For example:
class CRectangle
{
int length, breadth;
public:
void set_values (int,int);
int area (void);
} rect;
Declares a class (i.e., a type) called CRectangle and an object (i.e., a variable)
of this class called rect. This class contains four members: two data members of
type int (member x and member y) with private access (because private is the
default access level) and two member functions with public access: set_values() and
area(), of which for now we have only included their declaration, not their definition.
13
Notice the difference between the class name and the object name: In the
previous example, CRectangle was the class name (i.e., the type), whereas rect was
an object of type CRectangle. It is the same relationship int and a have in the
following declaration:
int length;
Where int is the type name (the class) and length is the variable name (the object).
After the previous declarations of CRectangle and rect, we can refer within the
body of the program to any of the public members of the object rect as if they were
normal functions or normal variables, just by putting the object's name followed by
a dot (.) and then the name of the member. All very similar to what we did with
plain data structures before. For example:
rect.set_values (3,4);
myarea = rect.area();
The only members of rect that we cannot access from the body of our
program outside the class are x and y, since they have private access and they can
only be referred from within other members of that same class.
// classes example
#include <iostream>
using namespace std;
class CRectangle
{
int length, breadth;
public:
void set_values (int,int);
int area ()
{
return
(length * breadth);
}
};
14
Function and Data Members
Functions are declared similar to variables, but they enclose their arguments
in parenthesis (even if there are no arguments, the parenthesis must be specified):
Data Members:
Data members are similar to a variable in C language. Data members can
be accessed through functions( member functions).
A data or function member of a class construct is accessed using .(period)
operator.
General Syntax for accessing a member of a class is
Objectname.data_member;
Objectname.member_function(list of arguments);
List of arguments is optional.
In the class CRectangel length, breadth are the data members. They also have the
access specifiers through which their method of access differs.
Default Arguments
15
default value is specified in a manner syntactically similar to a variable initialization.
For example, this declares myfunc() as taking one double argument with a default
value of 0.0:
Example:
Run
-----------------------------------------------------------------------------------------
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!
****************************************
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
16
Note that in the first statement both the arguments are default arguments
and in the second case only the missing argument(second argument) is replaced by
its default value.
The feature of default arguments can be utilized in enhancing the functionality of
the program without the need for modifying the old code referencing to functions.
For instance, the function in the above program
void printline(char = -,int = 70);
prints a line with default character - in case it is not passed explicitly. This function
can be enhanced to print multiple lines using the new prototype.
In this new function, the last parameter specifies the number of lines to be
printed and by default, it is 1. Therefore the old code referring to this function need
not be modified and new statements can be added without affecting the
functionality. If we give the function as printline(char =-,int=70, int = 2) then in
the above program the line will be printed twice.
Function overloading
17
x=y;
y=t;
}
void main()
{
char ch1, ch2;
cout<<enter two characters for ch1, ch2:;
cin>>ch1>>ch2;
swap(ch1,ch2);// compiler calls swap(char &a, char&b);
cout<<after swapping<<ch1<<ch2;
int a,b;
cout<<enter two integers for a,b:;
cin>>a>>b;
swap(a,b);
cout<<after swapping<<a<<b;
float c,d;
cout<enter two float values for c & d:;
cin>>c>>d;
swap(c,d);
cout<<after swapping<<c<<d;
}
Run
Friend Functions
The concept of encapsulation and data hiding dictate that non-member function
should not be allowed to access an objects private and protected members.
Friend functions are special functions grant a special privilege to access
private variables of the class.
This privilege must be given by the class itself.
Imagine the user wants a function to operate on objects of two different classes.
Sometimes, it is required to allow functions outside a class to access and
manipulate the private members of the class. In C++, this is achieved by using the
concept of friends.
18
The concept of friend permits a function or all the functions of another class to
access a different classs private members. The accessibility of class members in
various forms is shown in the below diagram.
The function declaration must be prefixed by the keyword friend whereas the
function definition must not. The function could be defined anywhere in the program
similar to a normal c++ function. The functions that are declared with the keyword
friend are called friend functions. A function can be a friend to multiple access.
Some of the special characteristics are:
The scope of the friend function is not limited to the class in which it has been
declared as a friend.
A friend function cannot be called using the object of that class; it is not in the
scope of the class. It can be invoked like a normal function without the use of
any object.
Unlike class member functions, it cannot access the class members directly.
However, it can use the object and the dot operator with each member name to
access both the private and public members.
It can be either declared in the private part or the public part of a class without
affecting its meaning.
Class X Class Y
private :
fy1()
Date or
function
rotected :
fy2()
friend class Y;
friend function1();
friend z:fz1();
Class Z
fz1()
function1
()
friend of X
fz2()
19
Fig: 1.6 Class members accessibility in various forms
GENERAL FORMAT:
Example:
#include <iostream.h>
class sample
{
int a,b;
public:
void setdata()
{
a=10;
b=20;
}
friend float mean(sample S);
};
float mean (sample S)
{
return float (S.a + S.b)/2.0;
}
void main()
{
sample a;
a.setdata();
cout<<mean(a);
}
20
Demonstrate const member functions.This program won't compile.
*/
#include <iostream>
using namespace std;
class Demo
{
int i;
public:
int geti() const {
return i; // ok
}
void seti(int x) const {
i = x; // error!
}
};
int main()
{
Demo ob;
ob.seti(1900);
cout << ob.geti();
return 0;
}
This program will not compile because seti() is declared as const. This
means that it is not allowed to modify the invoking object. Since it attempts to
change i, the program is in error. In contrast, since geti() does not attempt to
modify i, it is perfectly acceptable.
Mutable functions
Sometimes there will be one or more members of a class that you want a
const function to be able to modify even though you don't want the function to be
able to modify any of its other members. You can accomplish this through the use of
mutable. It overrides constness. That is, a mutable member can be modified by a
const member function. For example:
// Demonstrate mutable.
#include <iostream>
using namespace std;
class Demo {
mutable int i;
int j;
public:
int geti() const {
return i; // ok
}
void seti(int x) const {
i = x; // now, OK.
}
/* The following function won't compile.
void setj(int x) const {
j = x; // Still Wrong!
}
*/
};
int main()
21
{
Demo ob;
ob.seti(1900);
cout << ob.geti();
return 0;
}
Here, i is specified as mutable, so it may be changed by the seti() function.
However, j is not mutable and setj() is unable to modify its value.
Static Members
It has the following characteristics:
Access rule of the data member of a classis same for the static data member
also. If a static member is declared as a private category of a class then non-
member function cannot access these members. If a static member is
declared as public then any member function of the class can access.
Whenever a static data member is declared, it has a single copy. It will be
shared by all the instances of the class. That is, the static member becomes
global instance of the class.
Static data member should be created and initialized before the main()
function control block begins.
Static data member is used for the purpose of counting such as counting the
number of objects in a program, how many times a function called etc.
Syntax:
class classname
{
private:
static datatype variable; // static data declaration
public:
//member functions;
};
datatype classname::variable=value;//static data definition.
Keyword static should not be repeated again in the static data member definition
part.
A sample program to demonstrate how an automatic initialization of the
static member is carried out and the contents of the variables displayed is given
below:
22
#include<iostream.h>
class sample
{
static int a;
public :
void display()
{
cout<<automatic initialization of a is:<<a;
}
};
int sample::a;
void main()
{
sample x;
x.display();
}
Run:
automatic initialization of a is : 0
Example: 2
#include<iostream.h>
class sample
{
static int a;
public :
void display()
{
cout<<a<<endl;
}
void increment()
{
a=a+5;
}
};
int sample::a;
void main()
{
sample x;
cout<<Automatic initialization of a is:;
x.display();
x.increment();
cout<<Incremental value of a is:;
x.display();
}
Run:
Automatic initialization of a is: 0
Incremental value of a is: 5
Example: 3
#include<iostream.h>
class sample
23
{
static int a;
public :
void display()
{
cout<<a<<endl;
}
void increment()
{
a=a+5;
}
};
int sample::a=20;
void main()
{
sample x;
cout<< initialization of a is:;
x.display();
x.increment();
cout<<Incremental value of a is:;
x.display();
}
Run:
Automatic initialization of a is:20
Incremental value of a is: 25
24
int sample::c;
void main()
{
sample x;
x.display();
sample y;
y.display();
sample z;
z.display();
}
Run:
Object 1 is created
Object 2 is created
Object 3 is created
Example: 2:
The following program illustrates how the static member function can access only
static data member only.
#include <iostream.h>
class sample
{
static int c;
int b;
public:
static void display()
{
c++;
cout<<object <<is created<<endl;
cin b;
}
};
int sample::c;
void main()
{
sample x;
x.display();
sample y;
y.display();
sample z;
z.display();
}
Run:
Error:
Member b cannot be used without an object.// b is not static data member.
Objects
In c++, the class variables are known as objects. i.e Object is an instance of a
class.
25
Once a class has been declared, we can create variables of that type using the class
name.
For Example:
sample x; // creates a variable x of type sample.
Here, x is called an object of type sample.We may also declare and create
more than one object in one statement
sample x,y,z; // x,y,z are objects of type sample.
Objects can also be created when a class is defined by placing their names
immediately after the closing braces
class sample
{
int regno,mark1,mark2; // variable declaration
float res; // private by default
public:
void getdata(int a,int b,int c,float d); // function declaration
void showdata();
}x,y,z: // x,y,z are objects of type sample.
Example: The following program illustrates the use of creating array of objects.
#include<iostream.h>
#include<string.h>
class student
{
private:
int rollno;
string name;
string address;
public:
void setdetails (int roll, string studentname, string studadd)
{
rollno=roll;
name=studentname;
address=studadd;
}
void printdetails
{
cout<<rollno;
cout<<name;
cout<<address;
}
};
void main()
{
student arrayofstudent[2];
arrayofstudent[0].setdetails(1,anand,tindivanam);
arrayofstudent[1].setdetails(2,viswa,chennai);
}
26
Pointers and objects
In c++, pointers can also have an address for an object. They are known as
pointers to objects.
A pointer to an object contains an address of that object.
Pointer increment will increment the address by the size of the object.
Size of the object is determined by the size of all its non-static data members.
Either star . (dot) combination or the popular arrow notation can be used to
access the elements using object pointers.
.* and * are called pointer to member operators. These are referring to
pointers of members of the class.
.* is used when we access a member of a class using a pointer to it by an
object.
It is written as <object name> .* <pointer name>.
* is used when a pointer to a member of a class is used.
Constant objects
Example
#include <iostream.h>
#include<string.h>
class student
{
public:
int rollnumber;
string name;
string address;
27
student s2=s1;
s2.rollnumber=7; /* it wont compile because it tries to modify a
constant object */
}
Nested classes: Classes within classes
A class is declared as a member of another class. This is called nested class
or a class within another class.
The name of a nested class is local to the enclosing class.
Syntax
Class outerclassname
{
Private:
//data
Protected:
//data
Public:
//methods
Class innerclassname
{
Private:
//data of innerclass
Protected:
//data of innerclass
Public:
//methods of innerclass
}; //end of innerclass declaration
}://end of outerclass declaration
Outerclassname obj1;
Outerclassname::innerclassname obj2;
Member function of outer class can be defined as
Returntype outerclassname::outerfunctionname(list of arguments)
{
Statements;
}
Member function of inner class can be defined as
Returntype outerclassname::innerclassname::innerfunctionname(list of arguments)
{
Statements;
}
Member functions of an enclosing class have no special class to member of a
nested class, they obey the usual access rules.
The following program illustrates how the member function of the nested classes
are accessed.
#include <iostream.h>
class student
{
private:
int rno;
char name[20], sex;
public:
void get();
28
void out();
class date
{
private:
int d,m,y;
public:
void get();
void out();
class age
{
private:
int age;
public:
void getage();
void outage();
};
};
};
void student::get()
{
cout<<enter roll number name and sex<<endl;
cin>>rno>>name>>sex;
}
void student::out()
{
cout<<rno<<\t<<name<<\t<<sex<<\t;
}
void student::date::get()
{
cout<<enter day month year<<endl;
cin>>d>>m>>y;
}
void student::date::out()
{
cout<<d<<-<<m<<-<<y<<\t;
}
void student::date::age::getage()
{
cout<<enter age<<endl;
cin>>age;
}
void student::date::age::outage()
{
cout<<age;
}
void main()
{
student a;
student::date b;
student::date::age c;
a.get();
b.get();
c.getage();
cout<<roll<<\t<<name<<\t\t<<sex<<\t<<date<<-;
cout<<month<<-<<year<<\t\t<<age<<endl;
29
a.out();
b.out();
c.outage();
}
Run:
Input:
enter roll number name and sex
004
Anantharaj
M
enter day month year
07
04
1972
enter age
39
Output:
Roll name sex date-month-year age
004 anantharaj M 07-04-1972 39
Local classes
C++ allow classes to be defined inside functions as well. These classes are
called local classes. The function in which the class is defined is not a member
function of the class. It cannot access the private variables of the class. To access
private variables of the class it should become a friend to it.
A local class is declared within a function definition. Declarations in a local
class can only use type names, enumerations, static variables from the enclosing
scope, as well as external variables and functions.
For example:
30
int k() { return ::x; } // valid, global x
int l() { return g(); } // valid, extern function g
};
}
int main()
{
local* z; // error: the class local is not visible
//
...
}
Member functions of a local class have to be defined within their class
definition, if they are defined at all. As a result, member functions of a local class
are inline functions. Like all member functions, those defined within the scope of a
local class do not need the keyword inline.
A local class cannot have static data members. In the following example, an
attempt to define a static member of a local class causes an error:
void f()
{
class local
{
int f(); // error, local class has noninline
// member function
int g() {return 0;} // valid, inline member function
static int a; // error, static is not allowed for
// local class
int b; // valid, nonstatic variable
};
}
// ...
An enclosing function has no special access to members of the local class.
Constructors
Constructor is a special member function for automatic initialization of an object.
Whenever an object is created the special member function will be executed automatically.
For example
class username
{
private:
//data
31
public:
//username(); // constructor declaration
};
username::username() // constructor definition
{
statements;
}
#include <iostream.h>
class fib
{
private:
int f0,f1,fib;
public:
fib()
{
f0=-1;
f1=1;
}
void increment()
{
fib=f0+f1;
f0=f1;
f1=fib;
}
void disp()
{
Cout<<fib<<endl;
}
};
void main()
{
fib f;
int i;
for(i=1;i<=5;i++)
{
f.increment();
32
f.disp();
}
}
Output:
0
1
1
2
3
Default Constructor
Constructor with default arguments:
Like default arguments to functions, the constructors can also have the
default arguments.
For example
#include<iostream.h>
class sample
{
private:
float a,b,c;
public:
sample(float x=1.1, float y=2.2, float z=3.3) // no argument constructor
{
a=x;
b=y;
c=z;
}
void display()
{
cout<<a<<b<<c;
}
};
void main()
{
sample s1,s2;
sample s3(6.6);
sample s4(6.6,7.7);
sample s5(6.6,7.7,8.8);
s1.display();
s2.display();
s3.display();
s4.display();
s5.display();
}
Output:
1.1 2.2 3.3
1.1 2.2 3.3
6.6 2.2 3.3
6.6 7.7 3.3
6.6 7.7 8.8
33
Dynamic initialization of objects
When the initial value of an object may be provided during runtime then it is
known as dynamic initialization of object. It provides the flexibility of using different
format of data at run time depending upon the situation.
To call parameterized constructor we should pass the value to the object.
(i.e) for the constructor
integer(int a, int b)
it is invoked by integer a(10,18) this value can be get during run time
(i.e) for the above constructor
int p,q;
cin>>p>>q;
integer a(p,q);
34
t3.disp();
}
Output
5 10 15
5 10 15
4 8 12
Multiple constructors in a class
For example:
#include<iostream.h>
class sample
{
private:
int a,b,c;
public:
sample() // no argument constructor
{
a=5;
b=10;
c=15;
}
sample(int x) // one argument constructor
{
a=x;
b=0;
c=0;
}
sample(int x, int y) // Two argument constructor
{
a=x;
b=y;
c=20;
}
sample(int x, int y, int z) // Three argument constructor
{
a=x;
b=y;
c=z;
}
void display()
{
cout<<a<<b<<c;
}
};
void main()
35
{
sample s1,s2;
sample s3(4);
sample s4(10,20);
sample s5(10,20,30);
s1.display();
s2.display();
s3.display();
s4.display();
s5.display();
}
Output
5 10 15
5 10 15
4 0 0
10 20 30
10 20 30
Copy constructor
Copy constructor is used to declare and initialize an object from an already existing
object.
Syntax
classname newobject(old object);
classname newobject = oldobject;
For example :
#include<iostream.h>
class sample
{
private:
int a,b,c;
public:
sample() // no argument constructor
{
a=10;
b=15;
c=20;
}
sample(int x, int y, int z) // no argument constructor
{
a=x;
b=y;
c=z;
}
void display()
{
cout<<a<<b<<c;
}
};
void main()
36
{
sample s1;
sample s2=s2;//copy constructor
sample s3(4,8,12);
sample s4(s3);//copy constructor
s1.display();
s2.display();
s3.display();
s4.display();
}
Output
10 15 20
10 15 20
4 8 12
4 8 12
Dynamic Constructor
37
{
str n1(C++),n2(Programming),n3(Language),n4,n5;
n1.display();
n2.display();
n3.display();
n4.join(n1,n2);
n5.join(n4,n3);
n4.display();
n5.display();
}
Output
C++
Programming
Language
C++ Programming
C++ Programming Language
Note:
The above program uses two constructors. The first is an empty constructor.
The second constructor initializes the length of the string, allocates necessary space
for the string to be stored and creates the string itself. The member function join()
concatenates two strings. It estimates the combined length of the strings to be
joined and allocates memory for the combined string.
Destructors
Characteristics
The destructor is a member function whose name is the same as the class name but
is preceded by a tilde (~) symbol.
Syntax:
~ classname();
No argument should be passed.
Return type should not be given.
It cannot be declared static, const or volatile.
It should have public access in the class definition.
It may also be declared either inside the class or outside the class using scope
resolution operator.
38
syntax:
class username
{
private:
//data
public:
username(); // constructor declaration
~username();//destructor declaration
};
username::username() // constructor definition
{
statements;
}
username::~username() // destructor definition
{
statements;
}
For example:
#include<iostream.h>
int c=0;
class sample
{
public:
sample()
{
c++;
cout<<No.of object created<<c;
}
~sample();//destructor declaration
};
sample:~sample()//destructor definition
{
cout<<No.of object destroyed<<c;
c--;
}
void main()
{
cout<<Enter main;
sample s1,s2,s3,s4;
{
cout<<Enter Block1<<endl;
sample s5;
}
{
cout<<Enter Block2<<endl;
}
}
Output
Enter main
No.of object created 1
39
No.of object created 2
No.of object created 3
No.of object created 4
Enter Block1
No.of object created 5
No.of object destroyed 5
Enter Block2
No.of object destroyed 4
No.of object destroyed 3
No.of object destroyed 2
No.of object destroyed 1
Overloading
a. Function Overloading
Discussed in Unit-1
b. Operator Overloading
Syntax:
return_type operator operator_to_be_overloaded(list of parameters)
{
statements;
}
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 described the task.
40
}
returntype is the type of value returned by the specified operation.
1. First create a class that defines the data type that is to be used in the overloading
operation.
2. Declare the operator function in the public part of the class. It may be either a member
function or a friend function.
3. Define the operator function to implement the required operations.
Operators that are predefined in the C++ compiler can be overloaded. Users cannot
create new operators such as $,@etc.
The overloaded operator must have at least one operand that is of user defined type.
Users cannot change operator templates.
Each operator in C++ comes with its own template which defines certain aspects of its
use such as whether it is a binary operator or a unary operator and its order of
precedence. This template is fixed and cannot be altered by overloading.
For example, ++ and cannot be used except in unary operators. During overloading,
the prefixed increment / decrement and the postfix increment/decrement are not
distinguished.
Overloading and operator never gives a meaning which is radically different from its
natural meaning.
For example, Operator * may be overloaded to add the objects of two classes.
Overloaded operators follow the syntax rules of the original operators. They cannot be
overridden.
The following operators cannot be used for overloading purposes:
.(dot operator)
.* (Direct pointer to member)
:: Scope resolution operator
?: Conditional operator
sizeof(size in bytes operator)
#,## (preprocessing symbols)
Operator function must be either member function (non-static) or friend function. We
cannot use the friend functions to overload the following operators.
= Assignment operator
() Function call operator
[] Subscripting operator
->Class member access operator
41
If friend functions are used for overloading the unary operators then these
functions are called overloading unary operators with friends.
For example
/* This is the program to illustrate the use of unary operator with friends*/
#include<iostream.h>
class complex
{
private:
float real, imag;
public:
complex()
{
real=imag=0;
}
void getdata()
{
cout<<Enter real part<<endl;
cin>>real;
cout<< Enter imaginary part<<endl;
cin>>imag;
}
friend void operator (complex &c1);
void disp();
};
void complex::disp()
{
cout<<real<<+i(<<imag<<)<<endl;
}
// Keyword friend and scope resolution operator should not be used while defining
outside
void operator (complex &c1)
{
c1.real=-c1.real;
c1.imag=-c1.imag;
}
void main()
{
complex c1;
cout<<Enter complex inputs<<endl;
c1.getdata();
-c1;
c1.disp();
complex c2;
cout<<Enter complex inputs<<endl;
c2.getdata();
-c2;
c2.disp();
}
Output
42
Enter real part
10
Enter imaginary part
15
-10+i(15)
Enter complex inputs
Enter real part
-20
Enter imaginary part
-34
20+i(34)
If friend functions are used for overloading the binary operators then these
functions are called overloading binary operators with friends.
For example:
#include<iostream.h>
class complex
{
private:
float real, imag;
public:
complex()
{
real=imag=0;
}
void getdata()
{
cout<<Enter real part<<endl;
cin>>real;
cout<< Enter imaginary part<<endl;
cin>>imag;
}
friend complex operator +(complex c1, complex c2)
{
complex c;
c.real=c1.real+c2.real;
c.imag=c1.imag+c2.imag;
return(c);
}
friend complex operator-(complex c1, complex c2);
void disp();
};
void complex::disp()
{
cout<<real<<+i(<<imag<<)<<endl;
}
// Keyword friend and scope resolution operator should not be used while defining
outside
43
complex operator (complex c1, complex c2)
{
complex c;
c.real=c1.real-c2.real;
c.imag=c1.imag-c2.imag;
return(c);
}
void main()
{
complex c1,c2,c3;
cout<<Enter complex inputs 1<<endl;
c1.getdata();
cout<<Enter complex inputs 2<<endl;
c2.getdata();
c3=c1+c2;
cout<<Addition of complex number 1 and 2 is:;
c3.disp();
c3=c1-c2;
cout<<Subtraction of complex number 1 and 2 is:
c3.disp();
}
Output
For example:
#include<iostream.h>
class sample
{
private:
int x;
float y;
44
public:
sample(int, float); //constructor declaration
void operator=(sample abc);// operator function declaration
void display();
};
sample::sample(int one, float two)
{
x=one;
y=two;
}
void sample::operator=(sample abc)
{
x=abc.x+abc.x;
y=abc.y*5;
}
void sample::display()
{
cout<<x<<y;
}
void main()
{
sample s1(10,20.5);
sample s2(30,40.5);
s1.display();
s2.display();
s1=s2;
s1.display();
s2.display();
int a,b,c;
cin>>a>>b;
c=a+b;
cout<<c;
}
Output
10 20.5
30 40.5
60 202.5
30 40.5
2
3
5
The operators that operate on two operands are called binary operators.
The binary operators are +,-,*,/,%,<,> etc.
Whenever an arithmetic operator is used for overloading, the object oriented
function is invoked with single class objects.
For example:
45
/* This is the program to illustrate the use of + for finding the sum of two given
objects*/
#include<iostream.h>
class sample
{
private:
int v;
public:
sample();
sample(int);
sample operator +(sample abc);
void disp();
};
sample::sample()
{
v=0;
}
sample::sample(int one)
{
v=one;
}
sample sample::operator+(sample abc)
{
sample objc;
objc=v+objc.v;
return(objc);
}
void sample::disp()
{
cout<<v<<endl;
}
void main()
{
sample s1(10);
sample s2(10);
sample s3;
s3=s1+s2;
s1.disp();
s2.disp();
s3.disp();
int a,b,c;
cin>>a>>b;
c+a+b;
cout<<c;
}
Output:
10
20
30
2
3
5
46
Overloading of Comparison operator
Comparison and logical operators are binary operators that require two objects to be
compared and hence the result will be one of these <,<=,>,>=.==,!=. The return value of
the operator function is an integer. Object Oriented accepts an object on its right as a
parameter and the object on the left is passed by the this pointer.
For example:
Output
1
0
47
The operators that operate on only one operand are called unary operators.
E.g ++,-- Unary operators overloaded by member functions take no formal arguments
whereas when they are overloaded by friend functions they take a single argument.
For example:
/* The program to illustrate the use of unary operator overloading */
#include <iostream.h>
class sample
{
private:
int v;
public:
sample()
{
v=0;
}
void operator ++();
void operator ();
void disp()
{
cout<<v<<endl;
}
};
Output
0
1
2
1
0
48
Type conversions
The conversion from basic type to class type is easy to accomplish. The
constructors are used to initialize objects.
Consider the following constructor:
String::string(char *a)
49
{
length=strlen(a);
p = new char[length + 1];
strcpy(p,a);
}
This constructor builds a string type from a char* type variable a. The
variables length and p are data members of the class string. Once this constructor
is defined in the string class, it can be used for conversion from char* type to string
type.
For example:
string s1,s2;
char* name1=tcet;
char* name2 = vandavasi;
s1=string(name1);
s2=name2;
The statement
s1=string(name1);
first converts name1 from char* type to string type and then assigns the
string type values to the object s1. The statement
s2= name2;
also does the same job by invoking the constructor implicitly.
Let us consider another example of converting an int type to a class type.
class time
{
int hrs;
int mins;
public:
.
.
time(int t) // constructor
{
hours = t/60;
mins = t%60;
}
};
After the conversion, the hrs member of t1 will contain a value of 1 and
mins member a value of 40, denoting 1 hour and 40 minutes.
The constructors used for the type conversion take a single argument whose
type is to be converted.
50
This conversion is not so easy as the previous one. In C++ , an overloaded
casting operator is defined that could be used to convert a class type data to a
basic type. The general form of an overloaded casting operator function, usually
referred to as a conversion function, is;
operator typename()
{
(Function statements)
}
This function converts a class type data to typename. For example, the
operator double() converts a class object to type double, the operator int()
converts a class type object to type int, and so on.
Consider the following conversion function:
vector::operator double()
{
double sum = 0;
for(int i=0;i<size;i++)
sum=sum+v[i]*v[i];
return sqrt(sum);
}
This function converts a vector to the corresponding scalar magnitude. The
magnitude of a vector is given by the square root of the sum of the squares of its
components. The operator double() can be used as follows:
double length = double(v1);
or
double length =v1;
where v1 is an object of type vector. Both the statements have exactly the
same effect. When the compiler encounters a statement that requires the
conversion of a class type to a basic type, it quietly calls the casting operator
function to do the job.
The casting operator function should satisfy the following conditions.
It must be a class member
It must not specify a return type.
It must not have any arguments.
Since it is a member function, it is invoked by the object and, therefore, the
values used for conversion inside the function belong to the object that invoked the
functions. This means that the function does not need an argument.
In the string example described in the previous section, we can do the
conversion from string to char* as follows:
string::operator char*()
{
return (p);
}
51
There are situations where we would like to convert one class type data to
another class type.
Example:
objX=objY; // objects of different types
objX is an object of class X and objY is an object of class Y. The class Y type data
is converted to the class X type data and the converted value is assigned to the
objX. Since the conversion takes place from class Y to class X, Y is known as the
source class and X is known as the destination class.
Such conversions between objects of different classes can be carried out by
either a constructor or a conversion function. The compiler treats them the same
way. It depends upon where we want the type-conversion function to be located in
the source class or in the destination class.
We know that the casting operator function
Operator typename ()
Converts the class object of which it is a member to typename. The typename may
be a built-in type or a user-defined one (another class type). In the case of
conversions between objects, typename refers to the destination class. Therefore,
when a class needs to be converted, a casting operator function can be used (i.e
source class). The conversion takes place in the source class and the result is given
to the destination class object.
Now consider a single-argument constructor function which serves as an
instruction for converting the arguments type to the class type of which it is a
member. This implies that the argument belongs to the source class and is passed
to the destination class for conversion. This makes it necessary that the conversion
constructor be placed in the destination class.
Fig.2.1 illustrates these two approaches.
objX = objY // Y is a source class Class Y
Casting operator
Converted value of type X function
conversion here(source class)
Class X Class Y
Constructor function Data access function
Argument of type Y
conversion here(destination class)
52
Let us consider an example of an inventory of products in store. One way of
recording the details of the products is to record their code number, total items in
the stock and the cost of each item. Another approach is to just specify the item
code and the value of the item in the stock. The example shown below uses two
classes and shows how to convert data of one type to another.
53