C++ - Unit II

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 109

Programming in C++ using

Data Structures

Unit II
Classes and Objects
CLASS:
• Class is a group of objects that share common properties and relationships . A
class is a new data type that contains member variables and member functions that
operates on the variables.
• A class is defined with the keyword class.
• It allows the data to be hidden, if necessary from external use.
• When we defining a class, we are creating a new abstract data type that can be
treated like any other built in data type.
Generally a class specification has two parts:-
a) Class declaration - describes the type and scope of its members
b) Class function definition - describes how the class functions are implemented
Classes and Objects …Cont’d
Syntax:-

class class-name
{
private: The data hiding is the key feature of oops.
variable declarations; The use of keywords private is optional by
function declaration ; default, the members of a class are private.
The variables declared inside the class are
public: known as data members and the functions
variable declarations;
are known as members functions.
function declaration;
}; Only the member functions can have
access to the private data members and
• The members that have been declared as private functions.
private can be accessed only from with in However, the public members can be
the class. accessed from the outside the class.
The binding of data and functions together
• On the other hand , public members can be into a single class type variable is referred to
accessed from outside the class also. as encapsulation.
Classes and Objects …Cont’d
Syntax:-
class item
{
int member; Data Members
float cost;
public:
void getldata (int a ,float b); Member Functions
void putdata (void);
}

The class item contains two data members and two Member Functions, the data members are
private by default while both the functions are public by declaration.
The function getdata() can be used to assign values to the member variables member and cost,
and putdata() for displaying their values . These functions provide the only access to the data
members from outside the class.
Classes and Objects …Cont’d

CREATING OBJECTS:
When a class is defined, only the specification for the object is defined; no memory or storage is
allocated. To use the data and access functions defined in the class, you need to create objects. Syntax
: ClassName ObjectName;
Example: item x;
creates a variables x of type item. In C++, the class variables are known as objects. Therefore x is called an
object of type item. Item x, y ,z also possible.
class item
{
-----------
-----------
-----------
}x ,y ,z; //would create the objects x ,y ,z of type item.

Accessing data members and member functions:


The data members and member functions of class can be accessed using the dot(‘.’) operator with
the object. For example if the name of object is x and you want to access the member function with the
name printName() then you will have to write x.printName() .
Classes and Objects …Cont’d

Accessing data members


// C++ program to demonstrate accessing of data members
#include <iostream.h>
using namespace std;
class Name
{
// Access specifier
public:
// Data Members
string Myname;
// Member Functions()
void printname()
{
cout << “My name is: " << Myame;
}
};
int main() {
// Declare an object of class geeks
Name x;
// accessing data member
x.Myname = “Geetha"; Output:
// accessing member function
x.printname(); My name is: Geetha
return 0;
}
Classes and Objects …Cont’d
Defining and Accessing Member Functions in Classes
There are 2 ways to define a member function:
1. Inside class definition
2. Outside class definition

1. Outside the Class definition


Member function that are declared inside a class have to be defined separately outside the class.
Their definition are very much like the normal functions.

To define a member function outside the class definition we have to use the scope resolution
operator :: along with class name and function name.

An important difference between a member function and a normal function is that a member
function incorporates a membership. Identify label in the header. The ‘label’ tells the compiler which class
the function belongs to.

Syntax: return type class-name::function-name(argument declaration )


{
function-body
}
The member ship label class-name :: tells the compiler that the function, ‘function-name’ belongs to the
class, ‘class-name’ .
Classes and Objects …Cont’d
Characteristics of a Member function:
• Several different classes can use the same function name. The "membership label" will resolve
their scope, member functions can access the private data of the class .A non member function
can't do so.
• A member function can call another member function directly, without using the dot
operator.

2. Inside the Class definition:


Another method of defining a member function is to replace the function declaration by the actual
function definition inside the class .

Example: class Name


{
public:
string Myname;
int id;
// printid is defined inside class definition
void printid()
{
cout << “My id is: " << id;
}
};
C las ses an d Obje ct s … C on t’d

Defining and Accessing Member Functions in Classes // Definition of printname using scope resolution operator ::
void Name::printname()
{
In the below Example program cout << “My name is: " << Myname;
Function printid() is defined within the class, Name. }
Function printname is declared within the class and defined int main() {
outside the class using :: (Scope resolution operator) Name obj1;
obj1.Myname = “Madhu";
// C++ program to demonstrate function declaration outside class obj1.id=15;
#include <iostream.h> // call printname()
using namespace std; obj1.printname();
class Name cout << endl;
{ // call printid()
public: obj1.printid();
string Myname; return 0;
int id; }
// printname is not defined inside class definition
void printname(); Output:
// printid is defined inside class definition
void printid() My name is: Madhu
{ My id is: 15
cout << “My id is: " << id;
}
};
Classes and Objects …Cont’d

Making an Outside Function Inline:


We can define a Member function outside the class definition and still make it inline by just using the
qualifier inline in the header line of the function definition.

Example: class Name


{
public:
string Myname;
int id;
// printname is not defined inside class definition
void printname();
……..
……..
};
// Definition of printname using scope resolution operator ::
Inline void Name::printname()
{
cout << “My name is: " << Myname;
}
Clas sesa ndObj ects…Cont’d

Sample program using class in C++ to input subject mark void main()
and prints it. {
class marks
{ clrscr();
private : marks x;
int ml,m2;
public: x.getdata();
void getdata(); x.displaydata();
void displaydata();
}; }
void marks :: getdata()
Output:
{
cout<<”enter 1st subject mark:”; enter 1st subject mark: 76
cin>>ml; enter 2nd subject mark: 56
cout<<”enter 2nd subject mark:”;
cin>>m2; 1st subject mark: 76
} 2nd subject mark: 56
void marks:: displaydata()
{
cout<<”1st subject mark:”<<ml<<endl ;
cout<<”2nd subject mark:”<<m2;
}
Classes and Objects …Cont’d

void set::input(void) Function Definition 2


Nesting of member function:
{
A member function can be called by using its
cout<<”input values of m and n:”;
name inside another member function of the same
cin>>m>>n;
class. This is known as nesting of member functions.
}
#include <iostream.h> void set::display(void) Function Definition 3
class set {
{ cout<<”Largest value=”<<largest()<<”\n”;
int m,n;
}
public:
void input(void); void main() Calling the Function within a function
definition
void display (void); Function Declarations
void largest(void); {
}; set A;
int set::largest (void) Function Definition 1 A.input( );
{
A.display( );
if(m>n)
return m; }
else
Output:
return n;
} Input value of m and n 25 18
Largest value = 25
Classes and Objects …Cont’d

Private member functions:


Although it is a normal practice to place all the data items in a private section and all the
functions in public, some situations may require certain functions to be hidden from the outside
calls. Tasks such as deleting an account in a customer file or providing increment to an employee are
events of serious consequences and therefore the functions handling such tasks should have
restricted access. We can place these functions in the private section.
A private member function can only be called by another function that is a member of its class.
Even an object can not invoke a private function using the dot operator.
Class sample
{
int m;
void read (void);
Public:
void write (void);
void update(void);
};
Classes and Objects …Cont’d

Private member functions…Cont’d

if ‘s’ is an object of Class, sample, then

s.read(); // won’t work , as an object cannot access private functions.

is illegal. How ever the function read() can be called by the function update ( ) to update the
value of m.

void sample :: update(void)


{
read( );
}
Classes and Objects …Cont’d

Array with classes:

The Arrays can be used as member variables in a class.

Const int size=10 // provides value for array size


Class array
{
int a[size]; //’a’ is int type array
public:
void setval(void);
void display(void);
};

The array variable a{} declared as a private member of the class array can be used in the member
functions like any other variables. We can perform any operations on it.
Classes and Objects …Cont’d

void employee : : putdata ( )


#include<iostream.h> {
#include<conio.h> cout<<name <<endl;
class employee cout<<age<<endl;
{ cout<<sal<<endl;
private: return(0);
char name[20]; }
int age,sal;
public: int main()
void getdata(); employee emp[5]:
void putdata(); for( int i=0;i<5;i++)
}; {
emp[i].getdata();
void employee : : getdata () }
{ cout<<endl;
cout<<”enter name :”; for(i=0;i<5;i++)
cin>>name; {
cout<<”enter age :”; emp[i].putdata();
cin>>age; }
cout<<”enter salary:”; getch();
cin>>sal; return(0);
return(0); }
}
Classes and Objects …Cont’d

Static data member:


A data member of a class can be qualified as static. A static member variable has contain special
characteristics. They are
• It is initialized to zero when the first object of its class is created. No other initialization is
permitted.
• Only one copy of that member is created for the entire class and is shared by all the
objects of that class, no matter how many objects are created.
• It is visible only with in the class but its life time is the entire program.

Static variables are normally used to maintain values common to the entire class. For example a
static data member can be used as a counter that records the occurrence of all the objects.

Note that the type and scope of each static member variable must be defined outside the class
definition. This is necessary because the static data members are stored separately rather than as a
part of an object.
Classes and Objects …Cont’d

int item :: count ; //count defined


int main( )
Static Data Member Example {
item a,b,c;
a.get_count( );
#include<iostream.h> b.get_count( );
class item c.get_count( ):
{ a.getdata( ):
static int count; //count is static b.getdata( );
c.getdata( );
int number;
cout«"after reading data : "«endl;
public: a.get_count( );
void getdata(int a) b.gel_count( );
{ c.get count( );
number=a; return(0);
}
count++;
} Output:
void getcount(void) count:0
{ count:0
count:0
cout<<”count:”; After reading data
cout<<count<<endl; count: 3
} count:3
}; count:3

The static Variable count is initialized to Zero when the objects


created . The count is incremented whenever the data is read into an
object. Since the data is read into objects three times the variable count is
incremented three times. Because there is only one copy of count shared
by all the three object, all the three output statements cause the value 3
to be displayed.
Classes and Objects …Cont’d
Static Member Function: int test:: count;
int main()
A member function that is declared static has following
{
properties
1. A static function can have access to only other static test t1,t2;
members(Functions or Variables) declared in the same t1.set( );
class. t2.set( );
2. A static member function can be called using the class
name(instead of objects) as follows test :: showcount ( ); '
class - name :: function - name; test t3;
#include<iostream.h> t3.set( );
class test test:: showcount( );
{
int code; t1.showcode( ) ;
static int count; // static member variable t2.showcode( );
public: t3.showcode( );
void set(void)
{ return(0);
code=++count;
} output:
void showcode(void)
count: 2
{
cout<<”object member : “<<code<<end; count: 3
} object number 1
static void showcount(void) object number 2
{ cout<<”count=”<<count<<endl; }
}; object number 3
Classes and Objects …Cont’d

Objects as function arguments:


Like any other data type, an object may be used as A function argument. This can be done in
two ways
1. A copy of the entire object is passed to the function.
2. Only the address of the object is transferred to the function

The first method is called pass-by-value. Since a copy of the object is passed to the function,
any change made to the object inside the function do not effect the object used to call the function.
The second method is called pass-by-reference . When an address of the object is passed, the
called function works directly on the actual object used in the call. This means that any changes
made to the object inside the functions will reflect in the actual object .

The pass by reference method is more efficient since it requires to pass only the address of the
object and not the entire object.
Classes and Objects …Cont’d
Use of object as Function argument int main()
#include<iostream.h> {
class time
{ time T1,T2,T3;
int hours; T1.gettime(2,45);
int minutes;
public: T2.gettime(3,30);
void gettime(int h, int m) T3.sum(T1,T2);
{
hours=h; cout<<”T1=”;
minutes=m;
T1.puttime( );
}
void puttime(void) cout<<”T2=”;
{
cout<< hours<<”hours and:”; T2.puttime( );
cout<<minutes<<”minutes:”<<end; cout<<”T3=”;
}
void sum( time ,time); T3.puttime( );
}; return(0);
void time :: sum (time t1,time t2) .
{ }
minutes=t1.minutes + t2.minutes;
hours=minutes%60;
minutes=minutes%60;
hours=hours+t 1.hours+t2.hours;
}
Classes and Objects …Cont’d

void complex :: show ( complex c)


Returning objects: {
A function cannot only received objects as cout<<c.x<<” +j “<<c.y<<endl;
arguments but also can return them. }
int main( )
# include< iostream,h> {
class complex
{ complex a, b,c;
float x; a.input(3.1,5.65);
float y; b.input(2.75,1.2);
public:
c=sum(a,b);
void input( float real , float imag)
{ cout <<” a=”; a.show(a);
x=real; cout <<” b= “; b.show(b);
y=imag; cout <<” c=” ; c.show(c);
}
friend complex sum( complex , complex); return(0);
void show ( complex ); }
};
complex sum ( complex c1, complex c2)
{ output:
complex c3; a =3.1 + j 5.65
c3.x=c1.x+c2.x; b= 2.75+ j 1.2
c3.y=c1.y+c2.y;
return c3;} c= 5.85 + j 6.85
Classes and Objects …Cont’d

Pointer to members:
It is possible to take the address of a member of a class and assign it to a pointer. The address of a
member can be obtained by applying the operator & to a “fully qualified” class member name.
A class member pointer can be declared using the operator :: * with the class name.
Example: class A
{
private
int m;
public:
void show( );
};
We can define a pointer to the member m as follows :
int A :: * ip = & A :: m
The ip pointer created thus acts like a class member in that it must be invoked with a class object. In the
above statement. The phrase A :: * means “pointer - to - member of a class” . The phrase & A :: m means the “
Address of the m member of a class”

The following statement is not valid :


int *ip=&m ; // invalid
This is because m is not simply an int type data. It has meaning only when it is associated with the
class to which it belongs. The scope operator must be applied to both the pointer and the member.
Classes and Objects …Cont’d

The pointer ip can now be used to access the member m inside the member function (or friend function).
Assume that “a” is an object of “ A” declared in a member function . We can access "m" using the pointer ip as
follows.
cout<< a . * ip; // display
cout<< a.m; // same as above

ap=&a; // ap is pointer to object a


cout<< ap-> * ip; // display m
cout<<ap->m; // same as above

The dereferencing operator ->* is used as to access a member when we use pointers to both the object
and the member. The dereferencing operator .* is used when the object itself is used with the member pointer.
Note that * ip is used like a member name.

We can also design pointers to member functions which ,then can be invoked using the dereferencing operator
in the main as shown below.

(object-name.* pointer-to-member function)


(pointer-to -object -> * pointer-to-member function)

The precedence of ( ) is higher than that of .* and ->* , so the parenthesis are necessary.
Classes and Objects …Cont’d
Dereferencing operator: int main ( )
#include<iostream.h> {
class M
{ M n;
int x; void(M::*pf) (int,int) = &M :: set-xy;
int y;
public: (n*pf)( 10,20);
void set_xy(int a,int b) cout<<”sum=: ” << sum(n) << “\n”;
{
x=a; m *op = &n; //point to object n
y=b; ( op->* pf)(30,40); // invokes set-xy
}
friend int sum(M); Cout << ”sum=” << sum(n) << “\n” ;
}; return(0);
int sum (M m) }
{ output:
int M :: * px= &M :: x; //pointer to member x
int M :: * py- & m ::y; //pointer to member y sum= 30
M * pm=&m;
sum=70
int s=m.* px + pm-> *py;
return(s);
}
Constructors and Destructors

Constructors:
A constructor is a special member function whose task is to initialize the objects of its class . It is special
because its name is the same as the class name. The constructor is invoked when ever an object of its
associated class is created. It is called constructor because it construct the values of data members of the
class.
A constructor is declared and defined as follows:
//'class with a constructor
class integer
{
int m,n:
public:
Integer(void); //constructor declared
------------
------------
};
integer :: integer(void) //constructor defined
{
m=0;
n=0;
}
When a class contains a constructor like the one defined above it is guaranteed that an object created by
the class will be initialized automatically.
Constructors…Cont’d

For example:-
Integer int1; //object int 1 created

This declaration not only creates the object int1 of type integer but also initializes its data members m and n to zero.

Types of Constructors

1. Default Constructor
2. Parameterized Constructor
3. Copy Constructor

The constructor functions have some special characteristics:-


• These are called automatically when the objects are created.
• All objects of the class having a constructor are initialized before some use.
• These should be declared in the public section for availability to all the functions.
• Return type (not even void) cannot be specified for constructors.
• These cannot be inherited, but a derived class can call the base class constructor.
• These cannot be static.
• Default and copy constructors are generated by the compiler wherever required. Generated constructors are public.
• These can have default arguments as other C++ functions.
• A constructor can call member functions of its class.
• An object of a class with a constructor cannot be used as a member of a union.
• A constructor can call member functions of its class.
• We can use a constructor to create new objects of its class type by using the syntax.
Constructors…Cont’d

1. Default Constructors: Default constructor is the constructor which doesn’t take any argument. It has no
parameters.
// C++ program to illustrate the concept of Constructors
#include <iostream>
using namespace std;

class construct
{
public:
int a, b;

construct() // Default Constructor


{
a = 10;
b = 20;
}
};

int main()
{ Output:
// Default constructor called automatically when the object is created
construct c; a: 10
cout << "a: " << c.a << endl
<< "b: " << c.b; b: 20
return 1;
}

Note: Even if we do not define any constructor explicitly, the compiler will automatically provide a default constructor implicitly.
Constructors…Cont’d

2. Parameterized constructor:
The constructors that can take arguments are called parameterized constructors. Using parameterized constructor we
can initialize the various data elements of different objects with different values when they are created.
Example:-
class integer
{
int m, n;
public:
integer( int x, int y); //Parameterized Constructor
--------
---------
};
integer:: integer (int x, int y)
{
m=x;n=y;
}
When a constructor has been parametrized, the object declaration “integer int1;” may not work. We must pass the initial
values as arguments to the constructor function when an object is declared. This can be done in two ways.
• By calling the constructor explicitly
• By calling the constructor implicitly.
Example Declarations
integer int 1 = integer(0,100); // explicit call
integer int 1(0,100); //implicit call
Constructors…Cont’d

Class with Parameterized constructor:

#include<iostream.h>
class integer
{
int m,n;
public:
integer(int,int); // constructor declared
void display(void)
{
cout<<”m=:”<<m <<“\n”;
cout<<”n=”<<n <<“\n”;
}
};

integer :: integer( int x,int y) // constructor defined


{
m=x; n=y;
} output:
int main( ) object 1
{
integer int 1(0, 100); // constructor called implicitly m=0
integer int2=integer(25,75); // constructor called explicitly n=100
cout<<” \nobject1 “<<endl;
int1.display( );
object2
cout<<” \n object2 “<<endl;
m=25
}
int2.display( ); n=75
Constructors…Cont’d

Uses of Parameterized constructor:


• It is used to initialize the various data elements of different objects with different values when
they are created.
• It is used to overload constructors.

3. Copy Constructor:
A copy constructor is a member function which initializes an object using another object of the same
class. A constructor can accept a reference to its own class as a parameter as shown below. Such
constructors are called as Copy constructors.

Class A
{
-----
-----
public:
A(&A);
}:
Constructors…Cont’d

Class with Copy constructor:

#include<iostream>
using namespace std; int main()
class Point {
{
private: Point p1(10, 15); // Normal constructor is called here
int x, y;
public: Point p2 = p1; // Copy constructor is called here
Point(int x1, int y1)
{ cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
x = x1;
y = y1; cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();
}
return 0;
Point(Point &p2) // Copy constructor
{ }
x = p2.x;
y = p2.y;
}
Output:
int getX()
{ p1.x = 10, p1.y = 15
return x;
}
p2.x = 10, p2.y = 15
int getY()
{
return y;
}
};
Constructors…Cont’d

Constructor Overloading:
We can have more than one constructor in a class with same name, as long as each has a
different list of arguments. This concept is known as Constructor Overloading

• Overloaded constructors essentially have the same name (name of the class) and
different number of arguments.
• A constructor is called depending upon the number and type of arguments passed.
• While creating the object, arguments must be passed to let compiler know, which
constructor needs to be called.
Constructors…Cont’d

Constructor Overloading:
#include<iostream.h> sum :: sum(int p, float q ,double r)
#include<conio.h> {
class sum
{ a=p;
private; d=q;
int a; e=r;
int b;
int c; }
float d; void main( )
double e; {
public: clrscr( );
sum ( ) Constructor (Inline)
{ sum 1;
cout<<”enter a;”; sum m=sum(20,50);
cin>>a; sum n= sum(3,3.2,4.55);
cout<<”enter b;”;
cin>>b;
getch( );
cout<<”sum= “<<a+b<<endl; }
}
sum(int a, int b); Constructor
sum(int a, float d, double c); declarations
Output:
}; enter a : 3
enter b : 8
sum :: sum(int x,int y) Definition
{ sum=11
a=x; sum=70
b=y;
} sum=10.75
Constructors…Cont’d

Dynamic constructor:
The constructors can also be used to allocate memory while creating objects . This will enable
the system to allocate the right amount of memory for each object when the objects are not of the
same size, thus resulting in the saving of memory.

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


constructors of objects. The memory is allocated with the help of new operator.
Constructors…Cont’d

Dynamic Constructor:
#include<iostream.h> int main( )
#include<string.h>
class string {
{ char * first = “Joseph” ;
char *name; string name1(first),name2(“louis”),naine3( “LaGrange”),sl,s2;
int length; sl.join(name1,name2);
public:
string ( ) //constructor 1 s2.join(s1,name3);
{ namel.display( );
length=0; name2.display( );
name= new char [length+1]; /* one extra for \0 */
} name3.display( );
string( char *s) //constructor 2 s1.display( );
{ s2.display( );
length=strlen(s); Return 0;
name=new char [length+1];
strcpy(name,s); }
}
void display(void)
{ Output
cout<<name<<endl; Joseph
} Louis
void join(string &a, string &b);
}; language
void String :: join(String &a, String &b)
{
Joseph Louis
length=a. length +b . length; Joseph Louis Language
delete name;
name=new char[length+l]; /* dynamic allocation */
strcpy(name,a.name);
strcat(name,b.name);
};
Destructors:
A destructor, as the name implies, is used to destroy the objects that have been created by a
constructor. Like a constructor, the destructor is a member function whose name is the same as the class
name but is preceded by a tilde.
For Example: The destructor for the class integer can be defined as shown below:
~ integer( ) { }
A destructor never takes any argument nor does it return any value. It will be invoked implicitly by
the compiler upon exit from the program to clean up storage that is no longer accessible. It is a good
practice to declare destructors in a program since it releases memory space for future use.
New is used to allocate memory in the Constructor, we should use Delete to free that memory.
Destructor for the matrix class is defined as follows
matrix : : ~ matrix( )
{
for(int i=0; i<11;i++)
delete p[i];
delete p;
}
Destructors…Cont’d

#include<iostream.h>
int count=0;
class alpha output:-
{ Enter Main
public: no of object created 1
alpha( )
{ no of object created 2
count ++; no of object created 3
cout<<”\n no of object created :”<< count; no of object created 4
} Enter Block 1
~alpha( )
{ no of object created 5
cout<<”\n no of object destroyed :” << count; no of object destroyed 5
count--; Enter Block 2
}
};
no of object created 5
no of object destroyed 5
int main( ) Re-Enter Main
{ no of object destroyed 4
cout<<” \n \n Enter Main \n:”;
alpha A1, A2, A3, A4; no of object created 3
{ no of object created 2
cout<<” \n Enter Block 1 :\n”; no of object created 1
alpha A5;
}
{
cout<<” \n \n Enter Block2 \n”;
alpha A6;
}
cout<<\n Re-Enter Main \n:”;
return(0);
}
Operator overloading and Type Conversions

Operator Overloading:
In C++, we can make operators to work for user defined classes. This means C++ has the ability to
provide the operators with a special meaning for a data type, this ability is known as operator
overloading.
We can overload all the C++ operators except the following:
• Class members access operator (. , .*)
• Scope resolution operator (: :)
• Size operator(sizeof)
• Condition operator (? :)

Although the semantics of an operator can be extended, we can't change its syntax, the grammatical
rules that govern its use such as the no of operands precedence and associativety. For example the
multiplication operator will enjoy higher precedence than the addition operator.
When an operator is overloaded, its original meaning is not lost. For example, the operator +, which has
been overloaded to add two vectors, can still be used to add two integers.

Defining Operator Overloading:


To define an additional task to an operator, we must specify what it means in relation to the class to
which the operator is applied . This is done with the help of a special function called operator function,
which describes the task.
Operator overloading… Cont’d

Syntax:
return-type class-name :: operator op( arg-list)
{
function body
}
Where return type is the type of value returned by the specified operation and op is the operator being
overloaded. The op is preceded by the keyword operator, operator op is the function name.
Operator functions must be either member function, or friend function. A basic difference between them
is that a friend function will have only one argument for unary operators and two for binary operators, while a
member function has no arguments for unary operators and only one for binary operators. This is because the
object used to invoke the member function is passed implicitly and therefore is available for the member
functions. But in the case of Friend functions, Arguments may be passed either by value or by reference.
operator functions are declared in the class using prototypes as follows:-
vector operator + (vector); // vector addition
vector operator-( ); //unary minus
friend vector operator + (vuelor, vector); // vector add
friend vector operator -(vector); // unary minus
vector operator - ( vector &a); // substraction
int operator = =(vector); //comparision
friend int operator = =(vector ,vrctor); // comparision
Operator overloading… Cont’d

Vector is a data type of class and may represent both magnitude and direction or a series of points called elements.
The process of overloading involves the following steps:-
1. Create a class that defines the data type that is used in the overloading operation.
2. Declare the operator function operator op() in the public part of the class
It may be either a member function or friend function.
3. Define the operator function to implement the required operations.
Overloaded operator functions can be invoked by expressions such as
op x or x op;
for unary operators and
x op y
for binary operators. Op x (or x op) would be interpreted as either
operator op(x);
for friend functions. Similarly, the expression x op y would be interpreted as either
x. operator op (y)
In case of member functions, or
operator op (x, y);
in case of friend function. When both the forms are declared , standard argument matching is applied to
resolve any ambiguity.
Operator overloading… Cont’d

void space :: display(void)


Overloading Unary Operators {
cout << x << “ “;
A minus operator when used as a unary, takes just one cout << y << “ “;
operand. We know that this operator cout << z << “\n“;
}
Changes the sign of an operand when applied to a basic data item. Void space : : operator-()
The below example shows how to overload this operator so that it {
can be applied to an object in much the same way as is applied to an x = -x;
int or float variables. The unary minus when applied to an object y = -y;
should change the sign of its data items. z = -z;
}
#include <iostream>
int main()
Using namespace std: {
Class space space S;
{ S.getdata(10, -20, 30);
int x; cout << “s : “;
int y; S.display();
int z; -S ; //activates operator-() function
public: cout << “s : “;
void getdata(int a, int b, int c); S.display();
void display(void); return 0;
void operator-() // overload unary operator }
}; Output:
void space :: getdata(int a, int b, int c)
{ S : 10 -20 30
x = a; S : -10 20 -30
y = b;
Note: The function operator-() takes no arguments. It changes the sign of data members of
z = c;
the object S. Since this function is a member function of the same class, it can directly
} access the member of the object which activated it.
Operator overloading… Cont’d

It is possible to overload a unary minus operator using a friend function as follows;

Friend void operator-(space &s);


Void operator-(space &s)
{
s.x = -s.x;
s.y = -s.y;
s.z = -s.z
}

Note: Here the argument is passed by reference. It will nor work if we pass argument by value because
only a copy of the object that activated the call is passed to operator-(). Therefore, the changes made
inside the operator function will not reflect in the called object.
Int main()
Operator overloading… Cont’d

{
Overloading Binary Operators complex C1, C2, C3; // invokes constructor 1
C1 = complex(2.5, 3.5); // invokes constructor 2
Below program illustrates the Binary Operator overloading using Operator+() function C2 = complex(1.6, 2.7);
#include <iostream>
Using namespace std: C3 = C1 + C2; // invokes operator+() function
Class complex
{ cout << “C1 = “; C1. display();
cout << “C2 = “; C2. display();
float x; //real part cout << “C3 = “; C3. display();
float y; // imaginary part
public: return 0;
complex() { } // Constructor 1 }
complex(float real, float imag) // Constructor 2
Output:

{ C1 = 2.5 + j3.5
x = real; C2 = 1.6 + j2.7
y = imag;
C3 = 4.1 + j6.2
}
complex operator+(); // overload unary operator Note: Consider the function operator+(); its having following features. 1. It receives only one complex type
void display(void); argument explicitly.
}; 2. It returns a complex type value
3. It is a member function of complex.
complex complex :: operator+(complex c)
{ The function is expected to add two complex values and return a complex value as the result, but receives
complex temp; only one value as argument. The values come from C3 = C1 + C2
temp.x = x + c.x;
temp.y = y + c.y; A member function can be invoked only by an object of the same class. Here, the object C1 takes the
return (temp); responsibility of making the function and C2 plays the role of an argument that is passed to the function.
The above invocation statement is equivalent to C3 = C1.operator+(C2).
} Therefore, in the operator+() function, the data members of C1 are accessed directly and the data
void complex :: display(void) members of C2 (that is passed as an argument) are accessed using dot operator. Thus both objects are
{ available for the function. For example, in the statement temp.x = x + c.x;
cout << x << “ + j “ << y << “\n”;
} c.x refers to the object C2 and x refers to the object C1.temp.x is the real part of temp that has been
created specially to hold the results of addition of C1 and C2. The function returns the complex temp to be
assigned to C3.
Operator overloading… Cont’d

Rules for Operator Overloading:

1. Only existing operators can be overloaded. New operators can not be created.
2. The overloaded operator must have at least one operand that is of user-defined type.
3. We cannot change the basic meaning of an operator. That is to say, we cannot redefine the plus(+)
operator to subtract one value from the other.
4. Overloaded operators follow the syntax rules of the original operators. They cannot be overridden.
5. There are some operator that cannot be overloaded.
6. We cannot use friend functions to overload certain operators. However, member functions can be
used to overload them.
7. Unary operators, overloaded by means of a member function, take no explicit arguments and
return no explicit values, but, those overloaded by means of a friend function, take one reference
argument (the object of the relevant class).
8. Binary operators overloaded through a member function take one explicit argument and those
which are overloaded through a friend function take two explicit arguments.
9. When using binary operator overloaded through a member function, the left hand operand must
be an object of the relevant class.
10. Binary arithmetic operators such as +, _, * and / must explicitly return a value. They must not
attempt to change their own arguments.
Type Conversions

In a mixed expression, constants and variables are of different data types. The assignment operations
causes automatic type conversion between the operand as per certain rules.

The type of data to the right of an assignment operator is automatically converted to the data type of
variable on the left.

Consider the following example:


int x;
float y = 20.123;
x=y ;
This converts float variable y to an integer before its value assigned to x. Thus, the fractional part is
truncated.The type conversions are automatic as long as the data types involved are built in types.

we can also use the assignment operator in case of objects to copy values of all data members of right
hand object to the object on left hand. The objects in this case are of same data type. But of objects are of
different data types we must apply conversion rules for assignment. (Example: The statement C3 = C1 + C2
in Binary Operator overloading.)

There are three types of situations that arise where data conversion are between incompatible types.

1. Conversion from built in type to class type.

2. Conversion from class type to built in type.

3. Conversion from one class type to another class type.


Type Conversions …. Cont’d

1. Basic to Class Type


A constructor was used to build a vector object from an int type array. Similarly, we used another constructor to build a string type object from a
char* type variable. These are all examples where constructors perform a defacto type conversion from the argument type to the constructor’s class
type.
Consider the following constructor:
string :: string (char*a)
{
length = strlen (a);
p = new char[len+1];
strcpy (name,a);
}
This constructor builds a string type object from a char* type variable a. The variables length and p are data members of the class string. Once
this constructor has been defined in the string class, it can be used for conversion from char* type to string type.
Example
string s1 , s2;
char* namel = “Good Morning”;
char* name2 = “ STUDENTS” ;
s1 = string(name1);
s2 = name2;
The statement
s1 = string (name1);
first converts name 1 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.
Type Conversions …. Cont’d

Consider the following example


class time
{
int hours;
int minutes;
public:
---------
---------
time (int t) // constructor
{
hours = t / 60; //t in minutes
minutes = t % 60;
}
};
The following conversion statements can be used in a function:
time Tl; //object Tl created
int duration = 85;
Tl = duration; //int to class type

After this conversion, the hrs member of T1 will contain value of 1 and mins member contain a value of 25, denoting 1 hours and
25 minutes.

Note that the constructors used for the type conversion take a single argument whose type is to be converted.

In both the examples, the left-hand operand of = operator is always a class object. Hence, we can also accomplish this conversion
using an overloaded = operator.
Type Conversions …. Cont’d

2. Class to Basic Type


The constructor functions do not support conversion from a class to basic type. C++ allows us to define a overloaded casting operator that could be
used to convert a class type data to basic type. The general form of an overloaded casting operator function, usually referred to as a conversion function,
is:
operator typename ( )
{
-------------
--------------
}
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 ] ; //scalar magnitude
return sqrt(sum);
}
This function converts a vector to the corresponding scalar magnitude. Recall that the magnitude of a vector is given by the square root of the sum of
the square of its components. The operator double() can be used as follows

double length = double(VI) or double length = VI;

Where V1 is an object of type vector.


Type Conversions …. Cont’d

Both the above statements have exactly same effect. When the compiler encounters a statements 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 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
belongs to the object that invoked the function. This means that the function does not need an argument.
In the string example discussed earlier, we can do the conversion from string to char* as follows:
String :: operator char*( )
{
return (p) ;
}
Type Conversions …. Cont’d

3. One Class to Another Class Type


we would like to convert one class data type 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 conversion between objects of different classes can be carried out by either a constructor or a conversion
function. The compiler treat them the same way and which one to use, 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. The conversion takes
place in the source class and the result is given to the destination class object.
Type Conversions …. Cont’d

Let us consider a single-argument constructor function which serves as an instruction for converting the
argument's 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 must be placed in the destination class.

Here is the summary of all the three conversions. It shows that the conversion from a class to any other type
(or any other class) should make use of a casting operator in the source class. On the other hand, to perform
the conversion from any other type/class to a class type, a constructor should be used in the 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.
Function Overloading

Overloading refers to the use of the same thing for different purposes . C++ also permits overloading of
functions .This means that we can use the same functions that perform a variety of different tasks. This is known
as function polymorphism in oops.

Using the concepts of function overloading, we can design a family of functions with one function name but
with different argument lists in the functions call . The function would perform different operations depending on
the argument list in the function call. The correct function to be invoked is determined by checking the number
and type of the arguments but not on the function type.

For example an overloaded add() function handles different types of data as shown below.
//Declaration
int add(int a, int b); //prototype 1
int add (int a, int b, int c); //prototype 2
double add(double x, double y); //prototype 3
double add(int p, double q); //prototype 4
double add(double p , int q); //prototype 5

//function call
cout<<add(5,10); //uses prototype 1
cout<<add(15,10.0); //uses prototype 4
cout<<add(12.5,7.5); //uses prototype 3
cout<<add(5,10,15); //uses prototype 2
cout<<add(0.75,5); //uses prototype 5
A function call first matches the prototype having the same number and type of arguments and then calls the
appropriate function for execution.
Function Overloading….Cont’d

The function selection invokes the following steps:-

1. The compiler first tries to find an exact match in which the types of actual arguments are the same and use that
function .

2. If an exact match is not found the compiler uses the integral promotions to the actual arguments such as :
char to int
float to double to find a match

3. When either of them tails ,the compiler tries to use the built in conversions to the actual arguments and them uses
the function whose match is unique . If the conversion is possible to have multiple matches, then the compiler
Example:
long square (long n);
double square(double x);

A function call such as square(10); Will cause an error because int argument can be converted to either long
or double .There by creating an ambiguous situation as to which version of square( ) should be used.

4. If all the steps fails, then the compiler will try the user-defined conversions in combination with integral promotions
and built-in conversions to find a unique match. User-defined conversions are oftern used in handling class objects.
Function Overloading….Cont’d

Illustration of Function Overloading:


#include<iostream.h>
Using namespace std;

int volume(int);
double volume( double , int ); //Function Declaration (Prototype)
long volume(long ,int ,int);
main( )
{
cout << volume(10) << “\n”;
cout << volume(2.5, 8) << “\n”; //main function
cout<<volume(100L,75,15) << “\n”;
Return 0;
}
int volume( int s) //cube
{
return (s*s*s);
}
output:
double volume( double r, int h) //cylinder 1000
{ // Function Definitions 157.26
return(3.1416*r*r*h); 112500
}
long volume (long l, int b, int h) //rectangular box
{
return(l*b*h);
}
Inheritance

Reusability is yet another feature of OOP’s. For instance, the reuse of a class that has already been
tested, debugged and used many times can save us the effort of developing and testing the same again.

C++ strongly supports the concept of reusability. The C++ classes can be reused in several ways. Once a
class has been written and tested, it can be adopted by another programmers to suit their requirements.
This is basically done by creating new classes, reusing the properties of existing ones. The mechanism of
deriving a new class from an old one is called inheritance (or derivation). The old class is called base class
and the new one is called the derived class or subclass.

The derived class inherits some or all the properties from the base class. A class can also inherit
properties from more than one class or from more than one level. A derived class with only one base class is
called single inheritance and one with several base classes is called multiple inheritance. On the other
hand, the properties of one class may be inherited by more than one class is known as Hierarchical
inheritance. The mechanism of deriving a class from another ‘derived class’ is known as Multilevel
inheritance.
Inheritance… cont’d

Defining Derived Classes


A derived class can be specified by specifying its relationship with the base class in addition to its own details. The general form of defining
a derived class is :
class derived-class-name : visibility-mode base-class-name
{
--------------------
--------------------
};
The colon indicates that the derived-class-name is derived from the base-class-name. The visibility-mode is optional and, if present,
may be either private or public. The default visibility-mode is private. Visibility mode specifies whether the features of the base class are
privately derived or publicly derived.
Examples
class ABC : private XYZ //private derivation
{
members of ABC
};
class ABC : public XYZ //public derivation
{
members of ABC
};
class ABC : XYZ //private derivation (by default)
{
members of ABC
};
Inheritance… cont’d

• When a base class is privately inherited by a derived class, ‘public members’ of the base class become
‘private members’ of the derived class and therefore the public members of the base class can only be
accessed by the member functions of the derived class. They are inaccessible to the objects of the
derived class.

• On the other hand, when the base class is publicly inherited, ‘public member’ of the base class become
the ‘public member’ of the derived class and therefore they are accessible to the object of the derived
class.

• In both the cases, the private members are not inherited and therefore, the private members of a base
class will never become the member of its derived class.

• In inheritance, some of the base class data elements and member functions are ‘inherited’ into the
derived class. We can add our own data and member functions and thus extend the functionality of the
base class. Inheritance, when used to modify and extend the capabilities of the existing classes, becomes
a very powerful tool for incremental program development.
Single Inheritance
Below program illustrates single Inheritance. Here the base class int B :: get_a()
B and a derived class D. The class B contains one private data member, {
return a;
one public data member, and three public member functions. The class }
D contains one private data member and two public member
functions. void B :: show_a()
#include <iostream> {
cout << “a=“ << a << “\n”;
Using namespace std: }
Class B void D :: mul()
{ {
c = b * get_a();
int a; // private; not inheritable
}
public: void D :: display()
int b; // public; ready for inheritance {
void get_ab(); cout << “a=“ << get_a() << “\n”;
cout << “b=“ << b << “\n”;
int get_a(void); cout << “c=“ << c << “\n\n”;
void show_a(void); }
}; Int main()
{
class D : public B // public derivation D d;
{ d.get_ab();
int c; d.mul(); Output:
d.show_a();
public: d.display(); a = 5
void mul(void); a = 5
void display(void); d.b = 20; b = 10
d.mul();
} d.display();
c = 50
void B :: get_ab(void)
{ return 0; a = 5
a = 5; b = 10; } b = 20
} c = 100
Single Inheritance…Cont’d
The class D is a public derivation of the class B. Let us consider the case of private derivation
Therefore, D inherits all the public members of B and retains class d : private B // Private derivation
their visibility. Thus a public member of the base class B is also {
a public member of derived class D. The private member of B
int c;
cannot be inherited by D. Here is the class D
public:
void mul(void);
void display(void);
}

In the private derivation, the public members of the base


class become private members of the derived class.
Therefore, the object of D can not have direct access to the
public member function of B.

Here the object D have access to all the public members of B.


Making a Private Member Inheritable

A private data member can be inherited by modifying the visibility limit of the private member by making it public. This is make it
accessible to all the other functions of the program, thus taking away the advantage of data hiding.

C++ provides a third visibility modifier, protected, which serve a little purpose in the inheritance. A member declared as protected is
accessible by the member functions within its class and any class immediately derived from it. It cannot be accessed by functions outside
these two classes.

A class can now use all the three visibility modes as illustrated below:
class alpha
{
private: //optional
---------- //visible to member functions within its class
protected:
---------- //visible to member function of its own and derived class
public:
----------- //visible to all functions in the program
};

• When a protected member is inherited in public mode (public derivation)


It becomes protected in the derived class too and accessible by the member functions of the derived class.
It is also ready for further inheritance.

• When a protected member is inherited in private mode (private derivation)


It become private in the derived class and accessible by the member functions of the derived class, but
it is not available for further inheritance.

• When a base class is (both public and private members) in protected mode ( protected derivation)
Both public and private members of the base class become protected members of the derived class.
Making a Private Member Inheritable…Cont’d

The below table summarizes how the visibility of a base class members undergoes modifications in all the
three type of derivations.

The private and protected members of a class can be accessed by:


a. A function that is a friend of the class.
b. A member function of a class that is a friend of the class.
c. A member function of a derived class.

The friend functions and the member functions of a friend class have direct access to both the private and
protected data of the base class

The member function of a derived class can directly access only the protected data, and they can access the
private data through the member function of the base class.
Making a Private Member Inheritable…Cont’d

Below diagram illustrates how the access control mechanism works in various situations
Multilevel Inheritance
In Multilevel Inheritance, a class is derived form another derived class. In the below diagram, The
class A serves as a base class for a derived class B, which in turn serves as a base class for the derived class
C. The class B is known as the Intermediate base class since it provides a link for the inheritance between
A and C. The chain ABC is called inheritance path.

A derived class with multilevel inheritance is declared as follows


Class A { //body }; // Base class

Class B : public A { //body }; // B derived from A

Class C : public B { //body }; // C Derived from B

This process can be extended to any number of levels.

Consider the following example. Assume that the test result of a batch of students are stored in three
different classes. Class student stores the roll-number, class test stores the marks obtained in two subjects
and the class result contains the total marks obtained in the test. The class result can inherit the details of
the marks obtained in the test and the roll-number of student through multilevel inheritance.
Multilevel Inheritance… cont’d
#include <iostream> Void test :: get_marks(float x, float y)
{
Using namespace std: sub1 = x;
Class student sub2 = y;
{ }
protected: void test :: put_marks()
{
int roll_number; cout << “Marks in SUB1: “ << sub1<< “\n”;
public: cout << “Marks in SUB2: “ << sub2<< “\n”;
void get_number(int); }
Class result :: public test
void put_number(void); {
}; float total;
Void student :: get_number(int a) public:
void display(void)
{ };
roll_number = a; Void result :: display(void)
} {
total = sub1 + sub2;
void student :: put_number() put_number();
{ put_marks();
cout << “Roll Number: “ << roll_number << “\n”; cout << “ Total = “ << total << “\n”;
}
} Int main()
Class test :: public student {
{ result student;
student.get_number(111);
protected: Output:
student.get_marks(75.0, 59.5);
float sub1; student1.display(); Roll Number: 111
float sub2; Marks in SUB1: 75.0
public: return 0;
} Marks in SUB2: 59.5
void get_marks(float, float);
Total = 134.5
void put_marks(void);
};
Multiple Inheritance
A class can inherit the attributes of two or more classes. This is known as ‘multiple
inheritance’. Multiple inheritance allows us to combine the features of several existing classes
as a starring point for defining new classes. It is like the child inheriting the physical feature of
one parent and the intelligence of another. The syntax of the derived class is as follows:
Class D: visibility B-1, visibility B-2…
{
//body of D
}
Where, visibility may be either public or private.
The base classes are separated by commas.
Example:
class P : public M, public N
{
public:
void display(void);
};
Multiple Inheritance…Cont’d
class M Class P
{
protected: {
int m; protected:
public:
void get_m(int);
// from M Int m;
}; // from N Int n;
void M :: get_m(int x)
{
public: Void get_m(int);
m = x; // from M Void get_n(int);
} // from N Void display(void);
Class N // own member
{ };
protected:
int n; The member function display() can be defined as
public: follows:
void get_n(int);
};
Void P :: display(void)
void N :: get_n(int y) {
{
n = y; cout << “m = “ << m << “\n”;
} cout << “n = “ << n << “\n”;
The derived class P, as declared above , would, in effect,
contain all the members of M and N in addition to its own cout << “m*n = “ << m*n << “\n”;
members as shown below. };
Multiple Inheritance…Cont’d
include <iostream>
using namespace std;
Void P :: display(void)
class M {
{
protected: cout << “m = “ << m << “\n”;
int m; cout << “n = “ << n << “\n”;
public:
void get_m(int); cout << “m*n = “ << m*n << “\n”;
}; };
Class N
{
protected: int Main()
int n; {
public:
void get_n(int); P p;
}; p.get_m(10);
class P : public M, public N p.get_n(20);
{ p.display();
public:
return 0;
void display(void);
}; }

void M :: get_m(int x) Output:


{
m = 10
m = x;
}; n = 20
void N :: get_n(int y) m*n = 200
{
n = y;
};
Hierarchical Inheritance

Another interesting application of inheritance is to use it as a support to a hierarchical design of


a program. Many programming problems can be cast into a hierarchy where certain features of one
level are shared by many others below that level. Below examples shows a hierarchical classification
od student in a university and the classification of accounts in a commercial bank.

The base class will include all the features that are common to the subclasses. A subclass can
be constructed by inheriting the properties of the base class.
Hybrid Inheritance
There could be situations where we need to apply two or more types of inheritance to design a program. For
instance, consider the student result discussed in Multilevel Inheritance, assume that we have to give weightage for
sports before finalizing the results. The weightage for sports is stored in a separate class called sports.
The class, sports might look like
class sports
{
protected:
float score;
public:
void get_score(float)
void put_score(void);
};
The class, result will have both the multilevel and multiple inheritance and its declaration would be as follows
class result : public test, public sports
{
------------------
-------------------
};
Hybrid Inheritance… cont’d class sports
{
#include <iostream> protected:
Using namespace std: float score;
Class student public:
{ void get_score(float s)
protected: {
int roll_number; score = s;
public: {
void get_number(int a) void put_score(void);
{
{
cout << “Sports wt: “ << score << “\n”;
roll_number = a;
}
} };
void put_number(void) Class result :: public test, public sports
{ {
cout << “Roll Number: “ << roll_number << “\n”; float total;
} public:
Class test :: public student void display(void)
{ };
protected: Void result :: display(void)
{
float part1;
total = part1 + part2 + score;
float part2;
public:
put_number(); Output:
put_marks();
void get_marks(float x, float y) put_score();
Roll Number: 1234
{ cout << “ Total Score: “ << total << “\n”; Marks obtained
part1 = x; }
Int main()
Part1 = 27.5
part2 = y; { Part2 = 33.0
} result student;
Sports wt: 6
void put_marks(void) student.get_number(1234);
student.get_marks(27.5, 33.0); Total Score : 66.5
{ student.get_score(6.0)
cout << “Marks obtained: “ << “\n”; student1.display();
cout << “Part1 = “ << part1 << “\n”; return 0;
}
cout << “Part2 = “ << part2 << “\n”;
}
};
Virtual Base classes
We have just discussed a situation which would require the use of both multiple and multilevel inheritance. Consider
a situation, where all the three kinds of inheritance, namely multi-level, multiple and hierarchical inheritance, are
involved as shown in the below diagram.
The ‘child’ has two direct bass classes ‘parent1’ and
‘parent2’ which themselves has a common base class
‘grandparent’. The child inherits the traits of ‘grandparent’
via two separate paths. It can also inherit directly as shown
by the broken line. The grandparent is sometimes referred
to as indirect base class.
The inheritance by the child might pose some problems. All the public and protected members of ‘grandparent’ are
inherited into ‘child’ twice, first via ‘parent1’ and again via ‘parent2’. This means, ‘child’ would have duplicate set of
the members inherited from ‘grandparent’. The duplication of the inherited members can be avoided by making
common base class as the virtual base class while declaring the direct or intermediate base classes as shown below
class A // grandparent class B2 : public virtual A // parent2
{ {
-------- ----------
}; };
class B1 : virtual public A // parent1 class C : public B1,public B2 // child
{ {
-------- ------- // only one copy of A will be inherited
}; };
Pointers
Every variable is a memory location in which the assigned values are stored and every memory
location has its address defined which can be accessed using ampersand (&) operator which
denotes an address in memory.

Consider the following program which will print the address of the variables defined
#include <iostream>
using namespace std;
int main ()
{
int var1;
char var2[10];

cout << "Address of var1 variable: ";


cout << &var1 << endl;

Output:
cout << "Address of var2 variable: "; Address of var1 variable: 0xbfebd5c0
cout << &var2 << endl; Address of var2 variable: 0xbfebd5b6

return 0;
}
Pointers… Cont’d
What are Pointers?
A pointer is a variable whose value is the address of another variable. Like any variable or
constant, you must declare a pointer before you can work with it.
The general form of a pointer variable declaration is type *var-name;
• type - The pointer's base type; it must be a valid C++ data type
• var-name - The name of the pointer variable
• * - The asterisk is used to declare a pointer. In this statement the asterisk is being used
to designate a variable as a pointer.
Following are the valid pointer declaration
int *ip; // pointer to an integer
double *dp; // pointer to a double
float *fp; // pointer to a float
char *ch; // pointer to character

The actual data type of the value of all pointers, whether integer, float, character, or otherwise,
is the same, a long hexadecimal number that represents a memory address. The only difference
between pointers of different data types is the data type of the variable or constant that the pointer
points to.
Pointers… Cont’d
How to use a pointer? Consider the variable declaration int var = 20;
• Define a pointer variable. Int *ip
• Assigning the address of a variable to a pointer using unary operator (&) which returns the
address of that variable. *ip = &var
• Accessing the value stored in the address using unary operator (*) which returns the value of the
variable located at the address specified by its operand. *ip point to the value 20
#include <iostream>
using namespace std;
int main () {
int var = 20; // actual variable declaration.
int *ip; // pointer variable
ip = &var; // store address of var in pointer variable
cout << "Value of var variable: ";
cout << var << endl;
// print the address stored in ip pointer variable
cout << "Address stored in ip variable: "; Output:
cout << ip << endl; Value of var variable: 20
// access the value at the address available in pointer Address stored in ip variable: 0xbfc601ac
cout << "Value of *ip variable: "; Value of *ip variable: 20
cout << *ip << endl;
return 0;
}
Pointers… Cont’d
Null Pointers
It is always a good practice to assign the pointer NULL to a pointer variable in case you do not
have exact address to be assigned. This is done at the time of variable declaration. A pointer that is
assigned NULL is called a null pointer.
The NULL pointer is a constant with a value of zero defined in several standard libraries,
including iostream. Consider the following program

#include <iostream>
using namespace std;
Output:
int main () { The value of ptr is 0
int *ptr = NULL;
cout << "The value of ptr is " << ptr ;
return 0;
}
On most of the operating systems, programs are not permitted to access memory at address 0
because that memory is reserved by the operating system. However, the memory address 0 has
special significance; it signals that the pointer is not intended to point to an accessible memory
location. But by convention, if a pointer contains the null (zero) value, it is assumed to point to
nothing.
Pointers… Cont’d

To check for a null pointer you can use an if statement as follows −


if(ptr) // succeeds if p is not null
if(!ptr) // succeeds if p is null

Thus, if all unused pointers are given the null value and you avoid the use of a null pointer, you can
avoid the accidental misuse of an uninitialized pointer. Many times, uninitialized variables hold
some junk values and it becomes difficult to debug the program.
Pointers… Cont’d
Pointer Arithmetic
Pointer is an address which is a numeric value; therefore, you can perform arithmetic
operations on a pointer just as you can a numeric value. A limited set of arithmetic operations can
be performed on pointers which are:
• incremented ( ++ )
• decremented ( — )
• an integer may be added to a pointer ( + or += )
• an integer may be subtracted from a pointer ( – or -= )
• difference between two pointers (p1-p2)(Pointer comparison)
To understand pointer arithmetic, let us consider that ptr is an integer pointer which points to
the address 1000. Assuming 32-bit integers, let us perform the following arithmetic operation on
the pointer − ptr++
The ptr will point to the location 1004 because each time ptr is incremented, it will point to the
next integer. This operation will move the pointer to next memory location without impacting actual
value at the memory location.
If ptr points to a character whose address is 1000, then above operation will point to the
location 1001 because next character will be available at 1001.
Pointer Arithmetic … Cont’d
Incrementing a Pointer:
We prefer using a pointer in our program instead of an array because the variable pointer can
be incremented, unlike the array name which cannot be incremented because it is a constant
pointer. The following program increments the variable pointer to access each succeeding element
of the array
#include <iostream>
using namespace std;
const int MAX = 3;
int main () {
int var[MAX] = {10, 100, 200};
int *ptr;
// let us have array address in pointer.
ptr = var;
for (int i = 0; i < MAX; i++) {
cout << "Address of var[" << i << "] = ";
Output:
cout << ptr << endl;
Address of var[0] = 0xbfa088b0
cout << "Value of var[" << i << "] = "; Value of var[0] = 10
cout << *ptr << endl; Address of var[1] = 0xbfa088b4
// point to the next location Value of var[1] = 100
ptr++; Address of var[2] = 0xbfa088b8
} Value of var[2] = 200
return 0;
}
Pointer Arithmetic … Cont’d
Decrementing a Pointer:
The same considerations apply to decrementing a pointer, which decreases its value by the
number of bytes of its data type as shown below −

#include <iostream>
using namespace std;
const int MAX = 3;
int main () {
int var[MAX] = {10, 100, 200};
int *ptr;
// let us have address of the last element in pointer.
ptr = &var[MAX-1];
for (int i = MAX; i > 0; i--) {
cout << "Address of var[" << i << "] = ";
cout << ptr << endl;
cout << "Value of var[" << i << "] = "; Output:
cout << *ptr << endl; Address of var[3] = 0xbfdb70f8
// point to the previous location Value of var[3] = 200
Address of var[2] = 0xbfdb70f4
ptr--;
Value of var[2] = 100
}
Address of var[1] = 0xbfdb70f0
return 0; Value of var[1] = 10
}
Pointer Arithmetic … Cont’d
Pointer Comparisons:
Pointers may be compared by using relational operators, such as ==, <, and >. If p1 and p2 point to variables that
are related to each other, such as elements of the same array, then p1 and p2 can be meaningfully compared.
The following program modifies the previous example one by incrementing the variable pointer so long as the
address to which it points is either less than or equal to the address of the last element of the array, which is
&var[MAX - 1] −
#include <iostream>
using namespace std;
const int MAX = 3;
int main () {
int var[MAX] = {10, 100, 200};
int *ptr;
// let us have address of the first element in pointer.
ptr = var;
int i = 0;
while ( ptr <= &var[MAX - 1] ) {
cout << "Address of var[" << i << "] = ";
cout << ptr << endl; Output:
cout << "Value of var[" << i << "] = "; Address of var[0] = 0xbfce42d0
cout << *ptr << endl; Value of var[0] = 10
// point to the previous location Address of var[1] = 0xbfce42d4
ptr++; Value of var[1] = 100
i++; Address of var[2] = 0xbfce42d8
} Value of var[2] = 200
return 0;
}
Pointers… Cont’d
Pointers vs Arrays
Pointers and arrays are strongly related. In fact, pointers and arrays are interchangeable in
many cases. For example, a pointer that points to the beginning of an array can access that array by
using either pointer arithmetic or array-style indexing. Consider the following program −

#include <iostream>
using namespace std;
const int MAX = 3;
int main () {
int var[MAX] = {10, 100, 200};
int *ptr;
// let us have array address in pointer.
ptr = var;
for (int i = 0; i < MAX; i++) {
cout << "Address of var[" << i << "] = ";
cout << ptr << endl; Output:
cout << "Value of var[" << i << "] = "; Address of var[0] = 0xbfa088b0
cout << *ptr << endl; Value of var[0] = 10
// point to the next location Address of var[1] = 0xbfa088b4
ptr++; Value of var[1] = 100
} Address of var[2] = 0xbfa088b8
return 0; Value of var[2] = 200
}
Pointers vs Arrays… Cont’d
However, pointers and arrays are not completely interchangeable. For example, consider the
following program −
#include <iostream>
using namespace std;
const int MAX = 3;
int main () {
int var[MAX] = {10, 100, 200};

for (int i = 0; i < MAX; i++) {


*var = i; // This is a correct syntax
var++; // This is incorrect.
}
return 0;
}
It is perfectly acceptable to apply the pointer operator * to var but it is illegal to modify var
value. The reason for this is that var is a constant that points to the beginning of an array and can
not be used as l-value.
Because an array name generates a pointer constant, it can still be used in pointer-style
expressions, as long as it is not modified. For example, the following is a valid statement that assigns
var[2] the value 500 −
*(var + 2) = 500;
Above statement is valid and will compile successfully because var is not changed .
Pointers… Cont’d
Array of Pointers
Before we understand the concept of array of pointers, let us consider the following example,
which makes use of an array of 3 integers −
#include <iostream>
using namespace std;
const int MAX = 3;
int main () { Output:
int var[MAX] = {10, 100, 200}; Value of var[0] = 10
for (int i = 0; i < MAX; i++) { Value of var[1] = 100
cout << "Value of var[" << i << "] = "; Value of var[2] = 200
cout << var[i] << endl;
}
return 0;
}
There may be a situation, when we want to maintain an array, which can store pointers to an int or
char or any other data type available. Following is the declaration of an array of pointers to an integer −
int *ptr[MAX];
This declares ptr as an array of MAX integer pointers. Thus, each element in ptr, now holds a
pointer to an int value.
Array of Pointers… Cont’d
Following example makes use of three integers which will be stored in an array of pointers as follows −

#include <iostream>
using namespace std;
const int MAX = 3;
int main () {
int var[MAX] = {10, 100, 200};
int *ptr[MAX];

for (int i = 0; i < MAX; i++) {


ptr[i] = &var[i]; // assign the address of integer.
}

for (int i = 0; i < MAX; i++) {


cout << "Value of var[" << i << "] = "; Output:
cout << *ptr[i] << endl; Value of var[0] = 10
} Value of var[1] = 100
return 0; Value of var[2] = 200
}
Pointers… Cont’d
Pointer to Pointer (Multiple Indirection)
A pointer to a pointer is a form of multiple indirection or a chain of pointers. Normally, a pointer
contains the address of a variable. When we define a pointer to a pointer, the first pointer contains the
address of the second pointer, which points to the location that contains the actual value as shown
below.

A variable that is a pointer to a pointer must be declared as such. This is done by placing an
additional asterisk in front of its name. For example, following is the declaration to declare a pointer to
a pointer of type int − int **var;
When a target value is indirectly pointed to by a pointer to a pointer, accessing that value requires
that the asterisk operator be applied twice, as is shown below in the example −
Pointers… Cont’d
Pointer to Pointer Example:
#include <iostream>
using namespace std;
int main () {
int var;
int *ptr;
int **pptr;
var = 3000;
// take the address of var
ptr = &var;
// take the address of ptr using address of operator &
pptr = &ptr;
// take the value using pptr Output:
Value of var :3000
cout << "Value of var :" << var << endl; Value available at *ptr :3000
cout << "Value available at *ptr :" << *ptr << endl; Value available at **pptr :3000
cout << "Value available at **pptr :" << **pptr << endl;
return 0;
}
Pointers… Cont’d
Passing Pointers to Functions
To pass a pointer to a function, simply declare the function parameter as a pointer type. There are 3 ways
to pass C++ arguments to a function:
• call-by-value
• call-by-reference with pointer argument
• call-by-reference with reference argument// C++ program to illustrate call-by-methods in C++

Program to illustrate call-by-methods:


#include <iostream>
using namespace std;
//Pass-by-Value
int square1(int n)
{
//Address of n in square1() is not the same as n1 in main()
cout << "address of n1 in square1(): " << &n << "\n";

// clone modified inside the function


n *= n;
return n;
}
Passing Pointers to Functions…Cont’d
//Pass-by-Reference with Pointer Arguments //Call-by-Reference with Pointer Arguments
void square2(int *n) int n2=8;
{
//Address of n in square2() is the same as n2 in main() cout << "address of n2 in main(): " << &n2 << "\n";
cout << "address of n2 in square2(): " << n << "\n"; square2(&n2);
cout << "Square of n2: " << n2 << "\n";
// Explicit de-referencing to get the value pointed-to
*n *= *n; cout << "Change reflected in n2: " << n2 << "\n";
}
//Call-by-Reference with Reference Arguments
//Pass-by-Reference with Reference Arguments
void square3(int &n) int n3=8;
{ cout << "address of n3 in main(): " << &n3 << "\n";
//Address of n in square3() is the same as n3 in main() square3(n3);
cout << "address of n3 in square3(): " << &n << "\n";
cout << "Square of n3: " << n3 << "\n";
// Implicit de-referencing (without '*') cout << "Change reflected in n3: " << n3 << "\n";
n *= n; }
}
//Main program
void display()
int main()
{
{
//Call-by-Value
display();
int n1=8;
}
cout << "address of n1 in main(): " << &n1 << "\n";
cout << "Square of n1: " << square1(n1) << "\n";
cout << "No change in n1: " << n1 << "\n";
Pointers… Cont’d
When the above code is compiled and executed, it produces the following result −
address of n1 in main(): 0x7ffcdb2b4a44
address of n1 in square1(): 0x7ffcdb2b4a2c
Square of n1: 64
No change in n1: 8
address of n2 in main(): 0x7ffcdb2b4a48
address of n2 in square2(): 0x7ffcdb2b4a48
Square of n2: 64
Change reflected in n2: 64
address of n3 in main(): 0x7ffcdb2b4a4c
address of n3 in square3(): 0x7ffcdb2b4a4c
Square of n3: 64
Change reflected in n3: 64
In C++, by default arguments are passed by value and the changes made in the called function will not
reflect in the passed variable. The changes are made into a clone made by the called function.
If wish to modify the original copy directly (especially in passing huge object or array) and/or avoid the
overhead of cloning, we use pass-by-reference. Pass-by-Reference with Reference Arguments does not require
any clumsy syntax for referencing and dereferencing.
Pointers… Cont’d
Pointer to Classes
A pointer to a C++ class is done exactly the same way as a pointer to a structure and to access members of a
pointer to a class you use the member access operator -> operator, just as you do with pointers to structures. Also as
with all pointers, you must initialize the pointer before using it.
Example program to understand the concept of pointer to a class −
#include <iostream> int main(void) {
using namespace std; Box Box1(3.3, 1.2, 1.5); // Declare box1
class Box { Box Box2(8.5, 6.0, 2.0); // Declare box2
public: Box *ptrBox; // Declare pointer to a class.
// Constructor definition
Box(double l = 2.0, double b = 2.0, double h = 2.0) { // Save the address of first object
cout <<"Constructor called." << endl; ptrBox = &Box1;
length = l;
breadth = b; // Now try to access a member using member access operator
height = h; cout << "Volume of Box1: " << ptrBox->Volume() << endl;
}
double Volume() { // Save the address of second object
return length * breadth * height; ptrBox = &Box2;
}
private: // Now try to access a member using member access operator
double length; // Length of a box cout << "Volume of Box2: " << ptrBox->Volume() << endl;
double breadth; // Breadth of a box
double height; // Height of a box return 0;
}; }
Pointers to classes… Cont’d

When the above code is compiled and executed, it produces the following result −
Constructor called.
Constructor called.
Volume of Box1: 5.94
Volume of Box2: 102
Managing console input /output operations
Every program takes some data as input and generate processed data as output following the
familiar input-process-output cycle. Therefore it is essential to know how to provide input data and
how to present the results in a desired form. C++ supports a rich set of I/O functions and operations
to do this.
C++ uses the concept of stream and stream classes to implement its I/O operations with the
console and disk files.

C++ streams:
A stream is a sequence of bytes. It acts either as a source from which the input data can be
obtained or as a destination to which the output data can be sent. The source stream that provides
data to the program is called the input stream and the destination stream that receives output fron
the program is called output stream. In the other words, a program extracted the bytes from an
input stream and inserts bytes into an output stream as shown below
C++ streams…Cont’d
The data in the input stream can come from the keyboard or any other storage device. Similarly
the data in the output stream can go to the screen or any other storage device. The stream acts as
an interface between the program and the input/output device. Therefore, a C++ program handles
data independent of the devices used. C++ contain several pre-defined streams that are
automatically opened when a program begins its execution. These includes cin and cout.
C++ stream classes:
The C++ I/O system contains a hierarchy of classes that are used to define various streams to
deal with both the console and disk files. These classes are called stream classes Below diagram
shows the hierarchy of the stream classes used for input and output operations with the console
unit. These classes are declared in the header file iostream. The file should be included in all
programs that communicate with the console unit.
C++ stream classes…Cont’d

As seen in the above diagram, ios is the base class for istream (input stream) and ostream
(output stream) which are, in turn, base classes for iostream(input/output stream). The class ios is
declared as the virtual base class so that only one copy of its members are inherited by the
iostream.

The class ios provides the basic support for formatted and unformatted I/O operations. The
class istream provides the facilities for formatted and unformatted input while the class
ostream(through inheritance) provides the facilities for formatted output. The class iostream
provides the facilities for handling both input output streams. Three classes namely
istream_withassign, ostream_withassign and iostream_withassign add assignment operators to
these classes.
C++ stream classes…Cont’d
Stream classes for console operations:

Class name Contents


• Contains basic facilities that are used by all other input and output
Ios classes
(General input/ • Also contains a pointer to buffer object(streambuf object)
output stream class) • Declares constants and functions that are necessary for handling
formatted input and output operations
Istream • Inherits the properties of ios
(input stream) • Declares input functions such as get(), getline() and read()
• Contains overloaded extraction operator >>
Ostream • Inherits the property of ios
(output stream) • Declares output functions put() and write()
• Contains overloaded insertion operator <<
Iostream • Inherits the properties of ios istream and ostream through multiple
(input/output stream) inheritance and thus contains all the input and output functions
streambuf • Provides an interface to physical devices through buffers
• Acts as a base for filebuf class used ios files
Unformatted I/O Operations

Overloaded operators >> and<<


The Objects cin and cout for the input and output of data of various type. This has been made
possible by overloading operators >> and <<. The >> operator is overloaded in the istream class
and << is overloaded in the ostream class. The following is the format for reading data from
keyboard:
cin >> variable1 >> variable2 >> ………….. >> variable n
Variable1, variabl2, …. are valid C++ variable names that have been declared already. This statement
will cause the computer to stop the execution and look for the input data from the keyboard. The
input data for this statement would be
data1 data2…………..dataN
The input data are separated by white spaces and should match the type of variable in the cin
list. Spaces, newlines and tabs will be skipped.
Unformatted I/O Operations…Cont’d

The operator >> reads the data character by character and assigns it to the indicated location.
The reading for a variable will be terminated at the encounter of a white space or a character that
does not match the destination type. For example consider the following code
int code;
cin>> code;
Suppose the following data is entered as input
4258D
The operator will read the characters upto 8 and the value 4258 is assigned to code. The
character D remains in the input streams and will be input to the next cin statement. The general
form for displaying data on the screen is
cout << item1 << item2 << ………… << itemN
The items item1 through itemN may be variables or constants of any basic type..
Unformatted I/O Operations…Cont’d

put() and get() functions:


The classes istream and ostream define two member functions get() and put() respectively to
handle the single character input/output operations. There are two types of get() functions. Both
get(char *) and get(void) prototype to fetch a character including the blank space, tab and newline
character. The get(char *) version assigns the input character to its argument and the get(void)
version returns the input character.
Since these functions are members of input/output Stream classes, we must invoke them
using appropriate object. For Example
Char c;
cin.get( c ); //get a character from the keyboard and assigns it to c
while( c!=’\n’)
{
cout<< c; //display the character on screen
cin.get( c ); //get another character
}
This code reads and display a line of text. Remember, the operator >> can also be used to read a
character but it will skip the white spaces and newline character. The above while loop will not work
properly if the statement cin >> c; is used in place of cin.get(c);
Unformatted I/O Operations…Cont’d
The get(void) version is used as follows:
…………..
char c;
c= cin.get();
The value returned by the function get() is assigned to the variable c.
The function put(), a member of ostream class, can be used to output a line of text, character by
character. For example
cout.put(‘x’); //displays the character x and
cout.put(ch); //displays the value of variable ch.
The variable ch must contain a character value. We can also use a number as an argument to the
function put(). For example cout.put(68);
displays the character D. This statement will convert the int value 68 to a char value and displays character
whose ASCII value is 68.
The following segment of a program reads a line of text from keyboard and displays it on the screen
char c;
cin.get ( c ); // read a character
while( c!= ‘\n’)
{
cout.put(c); // display the character on screen
cin.get ( c);
}
Unformatted I/O Operations…Cont’d

Program to illustrate the use of put() and get(), character handling functions:
#include <iostream>
using namespace std;
int main()
{
int count=0;
char c;
cout<<”INPUT TEXT \n”;
cin.get( c );
while ( c 1=’\n’ )
{
cout.put( c);
count++; Input
cin.get( c ); Object oriented programming
} Output
cout<< “\n Number of characters =” <<count <<”\n”; Object oriented programming
Return 0; Number of characters=27
Unformatted I/O Operations…Cont’d

getline() and write() functions:


A line of text can be read and display effectively using the line-oriented input/output functions
getline() and write(). The getline() function reads a whole line of text that ends with a newline
character. This function can be invoked by using the object cin as follows:
cin.getline(line, size);
This function call invokes the function getline() which reads character input into the variable line.
The reading is terminated as soon as either the newline character ‘\n’ is encountered or size-1
characters are read(whichever occurs first). The newline character is read but not saved. instead it is
replaced by the null character. For example consider the following code:
char name[20];
cin.getline(name,20);
Assume that we have given the following input through key board:
Bjarne Stroustrup <press Return>
This input will be read correctly and assigned to the character array name.
Unformatted I/O Operations…Cont’d

Let us suppose the input is as follows:


Object Oriented Programming<press Return>
In this case ,the input will be terminated after reading the following 19 characters
Object Oriented Pro
Remember, the two blank spaces contained in the string are also taken into account.
We can also read string using the operator >> as follows
cin>>name;
But remember cin can read strings that do not contain white spaces. This means that cin can read just
one word and not a series of words such as “Bjarne Stroustrup”. But it can read the following string
correctly:
Bjarne_Stroustrup
After reading the string, cin automatically adds the terminating null character to the character array.
Unformatted I/O Operations…Cont’d
Program to demonstrates the use of >> and getline() for reading the strings.
#include <iostream> Output would be:
using namespace std; first run
int main() Enter city name:
{ Delhi
int size=20; City name: Delhi
char city[20]; Enter city name again:
City name now:
cout<<”Enter city name:\n “;
Enter another city name:
cin>>city;
Chennai
cout<<”City name:”<<city<<”\n\n”; New city name: Chennai
cout<<”Enter city name again: \n”; Second run
cin.getline(city, size); Enter city name:
cout<<”City name now:”<<city<<”\n\n”; New Delhi
cout<<”Enter another city name: \n”; City name: New
cin.getline(city, size); Enter city name again:
cout <<”New city name:”<<city<<”\n\n’; City name now: Delhi
Enter another city name:
return 0;
Greater Mumbai
}
New city name: Greater Mumbai
Unformatted I/O Operations…Cont’d

During fist run, the newline character ‘\n’ at the end of “Delhi” which is waiting in the input queue
is read by the getline() that follows immediately and therefore it dos not wait for any response to the
prompt ‘enter city name again’. The character’\n’ is read as an empty line.
During the second run, the word “Delhi”(that was not read by cin ) is read by function getline()
and, therefore, here again it does not wait for any input to prompt ‘Enter city name again:”. Note that
the line of text “Greater Mumbai” is correctly read by the second cin.getline(city, size); statement.

The write() function displays an entire line and has the following form:
cout.write(line, size)
The first argument line represents the name of the string to be displayed and the second argument size
indicates the number of characters to display. Note that it does not stop displaying the character
automatically when the null character is encountered. If the size is greater than the length of line, then
it displays beyond the bound of line.

The following Program illustrates how write() method displays a string


Unformatted I/O Operations…Cont’d
Program to demonstrates, How write() displaying a string.
#include <iostream>
#include<string> Output:
using namespace std; P
int main(0 Pr
{ Pro
char * string1=”C++”; Prog
char * string2 =”Programming”; Progr
int m = strlen(string1); Progra
int n = strlen(string2); Program
for (int i=1; i<n; i++) Programm
{ Programmi
cout.write(string2,i); Programmin
cout<<”\n”; Programming
} Programmin
for (i<n; i>0; i--) Programmi
{ Programm
cout.write(string2,i); Program
cout<<”\n”; Progra
} Progr
//concatenating strings Prog
cout.write(string1,m).write(string2,n); Pro
cout<<”\n”; Pr
//crossing the boundary P
cout.write(string1,10); C++ Programming
C++ Progr
return 0;
}
Formatted Console I/O Operations

C++ supports a number of features that could be used for formatting the output. These
features include:
• ios class function and flags.
• Manipulators.
• User-defined output functions.
The ios class contains a large number of member functions that would help us to format the
output in a number of ways. The most important ones among them are listed below
Function Task
Width() To specify the required field size for displaying an output value
precision() To specify the number of digits to be displayed after the decimal point
of float value
fill() To specify a character that is used to fill the unused portion of a field
setf() To specify format flags that can control the form of output display
(such as left-justification and right-justification)
unsetf() To clear the flags specified
Formatted Console I/O Operations…Cont’d

Manipulators are special functions that can be included in the I/O statements to alter the
format parameter of stream. Below table shows some important manipulator functions that are
frequently used. To access these manipulators, the file iomanip should be included in the program.

Manipulators Equivalent ios Function


setw() Width()
setprecision() precision()
setfill() fill()
setiosflags() setf()
resetiosflags() unsetf()

In addition to these standard library manipulators, we can create our own manipulator functions to
provide any special output formats.
End of Unit II

You might also like