Sunteți pe pagina 1din 53

EC6301 OBJECT ORIENTED PROGRAMMING AND DATA STRUCTURES SYLLABUS

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.

UNIT II INHERITANCE & POLYMORPHISM


Base Classes and Derived Classes Protected Members Casting Class pointers and
Member Functions Overriding Public, Protected and Private Inheritance Constructors and
Destructors in derived Classes Implicit Derived Class Object To Base Class Object Conversion
Composition Vs. Inheritance Virtual functions This Pointer Abstract Base Classes and Concrete
Classes Virtual Destructors Dynamic Binding.

UNIT III LINEAR DATA STRUCTURES


Abstract Data Types (ADTs) List ADT array-based implementation linked list implementation
singly linked lists Polynomial Manipulation - Stack ADT Queue ADT - Evaluating
arithmetic expressions

UNIT IV NON-LINEAR DATA STRUCTURES


Trees Binary Trees Binary tree representation and traversals Application of trees: Set
representation and Union-Find operations Graph and its representations Graph Traversals
Representation of Graphs Breadth-first search Depth-first search - Connected components.

UNIT V SORTING and SEARCHING


Sorting algorithms: Insertion sort - Quick sort - Merge sort - Searching: Linear search Binary Search

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

Structure of Procedure oriented language

Conventional programming, using high-level language such as COBOL,


FORTRAN and C are commonly known as Procedure oriented language (POP). In POP
number of function is written to accomplish the tasks such as reading, calculating
and printing.

Main program

Function-1 Function-2 Function-3

Function-4 Function-5

Function-6 Function-7 Function-8

Fig 1.1 Structure of Procedure oriented language

Some characteristics of procedure-oriented language.

Emphasis is on doing things (algorithms).


Larger programs are divided into smaller programs known as functions.
Most of the functions share global data.
Data move openly around the system from function to function.
Employs top-down approach in program design.

A Brief History of C++

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++.

The Need For C++

Although C is one of the most liked and widely used professional


programming languages in the world, there comes a time when its ability to handle
complexity is exceeded. Once a program reaches a certain size, it becomes so
complex that it is difficult to grasp as a totality. The purpose of C++ is to allow this
barrier to be broken and to help the programmer comprehend and manage larger,
more complex programs.
The STL (Standard Template Library) is a set of generic routines that you can
use to manipulate data. It is both powerful and elegant. But it is also quite large.
Subsequent to the first draft, the committee voted to include the STL in the
specification for C++. The addition of the STL expanded the scope of C++ well
beyond its original definition.

Progress Check

1. From what language is C++ derived?


2. What was the main factor that drove the creation of C++?

OBJECT ORIENTED PROGRAMMING CONCEPTS

C++ is object-oriented programming (OOP). Object-oriented programming


took the best ideas of structured programming and combined them with several
new concepts. A program can be organized in one of two ways: around its code
(what is happening) or around its data (who is being affected). Using only structured
programming techniques, programs are typically organized around code. This
approach can be thought of as code acting on data. Object-oriented programs
work the other way around. They are organized around data, with the key principle

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

FIG 1.2: OBJECT ORIENTED


PARADIGM

Object oriented programming as an approach that provides a way of


modularizing programs by creating partitioned memory area both data and
functions that can be used as templates for creating copies of such modules on
demand.
Object based and Object oriented programming are methods of visualizing
and programming the problem in a global way. They provide abstractions for all
entities involved in the process.

Categories of object-oriented languages

Object-based programming language


Object-oriented programming language

Features required for object-based programming Language

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

C++, Small talk, Object Pascal, Java

Four applications of OOPS

Real-time systems.
Simulation and modeling.
Object-oriented databases.
AI and expert systems.

Features of OOPS.

Emphasis is on data rather than on procedure.


Programs are divided into objects.
Data is hidden and cannot be accessed by external functions.
Follows bottom-up approach in program design Emphasis is on data rather than
procedure
Data structures are designed such that they characterize the objects
Objects may be communicate with each other through functions

Basic concepts of OOP

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

Objects are basic run-time entities in an object-oriented system. They may


represent a person, a place, a bank account, a table of data or any item that the
program has to handle. Each object has the data and code to manipulate the data
and theses objects interact with each other.
Example: The definition for a player object could be:
Player Object:
data:
health
strength
agility
type of weapon
type of armor
actions:
move
attack monster
get treasure
end;
Class
CLASS

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.

A class in C++ is an encapsulation of data members and functions that


manipulate the data.
The entire set of data and code of an object can be made a user defined data
type with the help of a class.
Objects are variables of the type of class.
A class is collection of objects with similar data type.

For example mango, apple and orange are members of the class fruit

Encapsulation

Wrapping up of data and function within the structure is called as


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.

Data members and member functions

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.

Example: int a,b; // a,b are data members


void getdata ( ) ; // member function

Dynamic binding or late binding

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

PET ANIMALS WILD


ANIMALS

CAT DOG LION TIGER

Fig: 1.4 Inheritance


Polymorphism

Polymorphism (from Greek, meaning many forms) is the the concept of


polymorphism is often expressed by the phrase one interface, multiple methods.
This means that it is possible to design a generic interface to a group of related
activities. Polymorphism helps reduce complexity by allowing the same interface to
specify a general class of action. It is the compilers job to select the specific action
(that is, method) as it applies to each situation.

Message passing (Communication)

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.

Object message information

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:

1. Creating classes that define objects and their behaviours.


2. Creating objects from class definitions.
3. Establishing communication among objects.

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.

DIFFERENCE BETWEEN PROCEDURE ORIENTED AND OBJECT ORIENTED


PROGRAMMING

Procedure Oriented Programming Object Oriented Programming


Top-down approach Bottom up approach
Large programs are divided into Programs are divided into
functions Objects
No reuse Reusability
Software complexity can not be Software complexity easily can
managed be managed
Up gradation is very difficult OOP can be easily upgraded
from small to large systems
Emphasis is on doing Emphasis is on data rather than
things(algorithms) procedure
Scalability is not available New data and functions can be
easily added whenever
necessary
E.g. C, COBOL, FORTRAN, etc., E.g. C++, JAVA, etc.,
Data driven Message passing

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;
}

You will follow these three steps:


1. Enter the program.
2. Compile the program.
3. Run the program.
Lets review two terms: source code and object code. Source code is the
human readable form of the program. It is stored in a text file. Object code is the
executable form of the program created by the compiler.

The First Sample Program Line by Line

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

A class in C++ is an encapsulation of data members and functions that


manipulate the data.
The entire set of data and code of an object can be made a user defined
data type with the help of a class.
Objects are variables of the type of class.
A class is collection of objects with similar data type.
For example mango, apple and orange are members of the class fruit.
A class is an expanded concept of a data structure: instead of holding
only data, it can hold both data and functions.
An object is an instantiation of a class. In terms of variables, a class
would be the type, and an object would be the variable.

GENERAL FORMAT OF CLASS

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.

Here is the complete example of class CRectangle:

// classes example
#include <iostream>
using namespace std;
class CRectangle
{
int length, breadth;
public:
void set_values (int,int);
int area ()
{
return
(length * breadth);
}
};

void CRectangle::set_values (int a, int b)


{
x = length;
y = breadth;
}
int main ()
{
CRectangle rect;
rect.set_values (3,4);
cout << "area: " << rect.area();
return 0;
}

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):

int sum(int to); /* Declaration of function sum with one argument */

int bar(); /* Declaration of function bar with no argument */

void foo(int ix, int jx);


/* Declaration of function foo with two arguments */

To actually define a function, just add its body:


int sum(int to)
{
int ix, ret;
ret = 0;
for (ix = 0; ix < to; ix = ix + 1)
ret = ret + ix;
return ret; /* return function's value */
} /* sum */

A function declared as a member (without the friend keyword) of a class is


called a member function.
Member functions are mostly given the attributes of public, because they
have to be called outside the class either in a program or in a function.

C only allows to pass function arguments by value. Consequently we cannot


change the value of one argument in the function.

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

C++ allows a function to assign a parameter a default value when no


argument corresponding to that parameter is specified in a call to that function. The

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:

void myfunc(double d = 0.0)


{
// ...
}
Now, myfunc() can be called one of two ways, as the following examples
show:
myfunc(198.234); // pass an explicit value myfunc(); // let function use default
The first call passes the value 198.234 to d. The second call automatically gives d
the default value zero.

Example:

// defarg.cpp Default arguments to functions


#include <iostream.h>
void printline (char = -, int = 70)
void main()
{
printline(); // uses both default arguments
printline(!); // uses 2nd argument as default
printline(*,40) // ignores default arguments
printline(A, 50);
}
void printline(char ch, int repeatcount)
{
int I;
cout<<endl;
for(i=0;i<repeatcount;i++)
cout<<ch;
}
}

Run
-----------------------------------------------------------------------------------------
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!
****************************************
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

In main() , when the compiler encounters the statement


printline();
it is replaced by the statement printline (-,70); internally by substituting the
missing arguments.
Similarly the statement
printline(!);
is replaced by printline (!,70);

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.

void printline (char = -,int = 70, int=1);

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

Function polymorphism or function overloading is a concept that allows


multiple functions to share the same name with different argument types. Function
polymorphism implies that the function definition can have multiple forms.
Assigning one or more function body to the same name is known as function
overloading or function name overloading.

//swap.cpp multiple swap functions with different type of arguments


#include <iostream.h>
void swap (char &x, char &y)
{
char t ; // temporary used in swapping
t=x;
x=y;
y=t;
}
void swap (int &x, int &y)
{
int t;
t=x;
x=y;
y=t;
}
void swap (float &x,f float &y)
{
float t;
t=x;

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

enter two characters for ch1,ch2: a n


after swapping n a

enter two integers for a,b: 10 50


after swapping 50 10

enter two float values for c & d: 10.5 7.3


after swapping 7.3 10.5

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:

friend return type function_ name(arguments list)

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);
}

Const and Volatile functions

Class member functions may be declared as const, which causes this to be


treated as a const pointer. Thus, that function cannot modify the object that
invokes it. Also, a const object may not invoke a non-const member function.
However, a const member function can be called by either const or non-const
objects.
To specify a member function as const, use the form shown in the following
example.
class X
{
int some_var;
public:
int f1() const; // const member function
};
As you can see, the const follows the function's parameter declaration. The
purpose of declaring a member function as const is to prevent it from modifying
the object that invokes it. For example, consider the following program.
/*

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.

Volatile Member Functions

Class member functions may be declared as volatile, which causes this to


be treated as a volatile pointer. To specify a member function as volatile, use the
form shown in the following example:
class X
{
public:
void f2(int a) volatile; // volatile member function
};

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

Static member functions

Keyword static is used to precede the member function to make a member


function as static member function.
Static member function can manipulate only on static data member of the
class.
Static member function acts as global for member of its class without
affecting the rest of the program.
Static & non-static member function cannot have the same name and the
same argument type.
Example: 1:
The following program illustrates the use of static member function to check how
many instances of the class objects are created.
#include <iostream.h>
class sample
{
static int c;
public:
static void displa()
{
c++;
cout<<object <<is created<<endl;
}
};

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.

Array of objects can be created in the following manner.


sample x[5]; // x is the object for the class sample with 5 instances.

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

Const objects are objects that are not modifiable.


C++ provides not allowing access of the object to a normal member function.
Const object is not allowed to do operations which modify the object. Even
public variables of the object are not modifiable.

Example
#include <iostream.h>
#include<string.h>
class student
{
public:
int rollnumber;
string name;
string address;

void printdetails() const


{
cout<< rollnumber;
cout<<name;
cout<< address;
}
};
void main()
{
const student s1;
s1.rollnumber=1001;
s1.name=senthilkumar;
s1.address=desur;
s1.printdetails();

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:

int x; // global variable


void f() // function definition
{
static int y; // static variable y can be used by
// local class
int x; // auto variable x cannot be used by
// local class
extern int g(); // extern function g can be used by
// local class

class local // local class


{
int g() { return x; } // error, local variable x
// cannot be used by g
int h() { return y; } // valid,static variable y

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.

Restrictions on the use of local classes

They cannot use auto local variables of the container function.


They can access static local variables or extern variables of the container
function.
They cannot contain static member themselves.
They cannot define their functions outside the class boundaries.
Their private variables are not available to container function unless it is
declared as friend.

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;
}

Syntax rules for writing constructor function

Constructor name must be the same as that of its class name.


It is declared with no return type (not even void)
It will not return any value.
It may be declared either within a class or outside the class.
It may not be static.
It should have public or protected access within a class and only in rare
occasion it should be declared private.

Sample program to illustrate the use of constructor

#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);

Parameterized constructors (Constructor with parameter)

If arguments are passed to constructors then those constructors are called


constructors with parameters or Parameterized constructor.
Arguments to the constructors should be given when an object is created.
The argument data type should match the member data type.
Example:
#include<iostream.h>
class test
{
int a,b,c;
public:
test()
{
a=5;
b=10;
c=15;
}
test(int x, int y, int z)
{
a=x;
b=y;
c=z;
}
void disp()
{
cout<<a<<b<<c;
}
};
void main()
{
test t1,t2;
test t3(4,8,12);
t1.disp();
t2.disp();

34
t3.disp();

}
Output
5 10 15
5 10 15
4 8 12
Multiple constructors in a class

If there is more than one constructor in a class then it is called multiple


constructors.
Each constructor differs from other by the number of parameters or
arguments.

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

Allocation of memory to objects at the time of their construction is known as


dynamic construction of objects.
The memory is allocated with the help of the new operator.
Example:
#include<iostream.h>
#include<string.h>
class str
{
private:
char *name; //input string;
int length; //length of the string;
public:
str() //constructor 1
{
length=0;
name=new char(length+1);
}
str(char *s) //constructor 2
{
length=strlen(s);
name=new char(length+1); // one additional space for null character
}
void display()
{
cout<<name;
}
void join(str &s1,str &s2)
{
length =s1.length+s2.length;
name=new char(length+1);
strcpy(name,s1.name);
strcat(name,s2.name);
}
};
void main()

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

A destructor is a function that automatically executes when an object is destroyed.


It is used to destroy the objects that have been created by a constructor.
It is used to release space on the heap.
The compiler calls the destructor automatically whenever there is an exit operation
from a function, block or program.

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

There are two types of overloading.


They are
a. Function overloading
b. Operator overloading

a. Function Overloading
Discussed in Unit-1

b. Operator Overloading

It is the process of defining an additional task to a predefined operator is called


operator overloading.
Existing operator can only be overloaded.
Operator overloading can be carried out by means of either member functions or
friend functions.

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.

The general form of an operator function is defined outside the class.

return_type classname::operator operator_to_be_overloaded(list of parameters)


{
function body; //Task defined

40
}
returntype is the type of value returned by the specified operation.

The process of overloading involves the following steps

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.

Rules for overloading an operator

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

Overloading through friend functions


Overloading of Unary operators with friends

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

Enter complex inputs

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)

Overloading of Binary operators with friends

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

Enter complex inputs 1


Enter real part
2
Enter imaginary part
2
Enter complex inputs 2
Enter real part
3
Enter imaginary part
3
Addition of complex number 1 and 2 is:5 +i(5)
Subtraction of complex number 1 and 2 is -1+i(-1)

Overloading the assignment operator

Assignment operator is a unary operator because it is connected only to the entity on


the right (that is the operand).

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

Overloading of Binary operator

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:

/* This is the program to demonstrate how to overload a less than operator in a


program to compare two classes of objects */
#include<iostream.h>
class sample
{
private:
int v;
public:
sample();
sample(int);
int operator<(sample abc);
void disp();
};
sample::sample()
{
v=0;
}
sample::sample(int one)
{
v=one;
}
int sample::operator<(sample abc)
{
return(v<abc.v);
}
void sample::disp()
{
cout<<v<<endl;
}
void main()
{
sample s1(10);
sample s2(20);
cout<<(s1<s2)<<\n;// if the condition is true then it returns a 1 otherwise it
returns a 0
cout<<(s2<s1);
}

Output
1
0

Overloading of Unary operators

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;
}
};

void sample::operator ++()


{
v++;
}
void sample::operator --()
{
v--;
}
void main()
{
sample s1;
s1.disp()
s1++;
s1.disp();
++s1;
s1.disp();
s1--;
s1.disp();
--s1;
s1.disp();
}

Output
0
1
2
1
0

48
Type conversions

In C the automatic type conversion to the operands is available. Similarly,


an assignment operation also causes the automatic type conversion. The type of
data to the right of an assignment operator is automatically converted to the type
of the variable on the left. For example,
int average;
float avg = 98.75;
average = avg;
convert avg to an integer before its value is assigned to average. Thus, the
fractional part is truncated. The type conversions are automatic as long as the data
types involved are built-in types.
But this rule does not hold good for the user defined data types.
For example,
Consider the following statements that add two objects and then assigns the result
to the third object.
obj3 = obj1 + obj2; // obj1,obj2,obj3 are class type objects.
When the objects are of the same class type, the operations of addition and
assignment are carried out without any difficulty and the compiler does not make
any complaints. In the case of class objects, the values of all the data members of
the right-hand object are copied into the corresponding members of the object on
the left-hand.
The compiler does not support automatic type conversion for user-defined
data types.
Three types of situations might arise to the data conversion between
incompatible types.
1. Conversion from basic type to class type.
2. Conversion from class type to basic type.
3. Conversion from one class type to another class type.

Type conversions at a glance


Table 2.1 Type conversions
Conversion takes place in
Conversion required
Source class Destination class
Basic -> Class Not Applicable Constructor
Class -> Basic Casting Operator Not Applicable
Class -> Class Casting Operator Constructor

Basic -> Class Type

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;
}
};

The following conversion statements can be used in a function;

time t1; // object t1 created


int duration = 100;
t1 = duration; // int to class type

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.

Class -> Basic Type

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);
}

One Class -> Another Class Type

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)

When a conversion using a constructor is performed in the destination class,


we must be able to access the data members of the object sent (by the source
class) as an argument. Since data members of the source class are private, we must
use special access functions in the source class to facilitate its data flow to the
destination class.

A Data Conversion Example

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.

/* data conversion program */


#include<iostream.h>
using namespace std;
class invent2 // destination class declared

class invent1 // source class


{
int code; // item code
int items; // no.of items
float price; // cost of each item
public:
invent1(int a, int b, float c)
{
code = a;
items = b;
price = c;
}
void putdata()
{
cout<<code: <<code<<\n;
cout<<items: <<items<<\n;
cout<<value: <<price<<\n;
}
int getcode() {return code;}
int getitems() {return items;}
float getprice() {return price;}
operator float() {return (items * price);}

/* operator invent2() //invent1 to invent2


{
invent2 temp;
temp.code = code;
temp.value = price * items;
return temp;
} */
}; // end of source class

class invent2 // destination class


{

53

S-ar putea să vă placă și