CPP by Sourav Kumar Giri PDF
CPP by Sourav Kumar Giri PDF
CPP by Sourav Kumar Giri PDF
On
Object Oriented Programming
using
C++
Er. Sourav Kumar Giri
HOD, Department of Computer Science & Engg.
Srinix College Of Engineering, Baleswar.
E-mail: [email protected]
SYLLABUS
Module I (08 hrs)
Introduction to object oriented programming, user defined types, structures, unions, polymorphism,
and encapsulation. Getting started with C++ syntax, data-type, variables, strings, functions, default
values in functions, recursion, namespaces, operators, flow control, arrays and pointers.
CONTENTS
Chapter No
Chapter Name
Chapter 1
Introduction
Chapter 2
30
Chapter 3
Inheritance
48
Chapter 4
Polymorphism
64
Chapter 5
Operator Overloading
73
Chapter 6
Exception Handling
82
Chapter 7
92
Chapter 8
Templates
99
Chapter 9
107
Chapter 10
Namespace
112
120
Page No
Chapter 1
Procedure/ structure oriented Programming
Conventional programming, using high level languages such as COBOL, FORTRAN and C, is
commonly known as procedure-oriented programming (POP).
In the procedure-oriented approach, the problem is viewed as a sequence of things to be done
such as reading, calculating and printing. A number of functions are written to accomplish these
tasks.
The primary focus is on functions.
Global Data
Global Data
Function-1
Function-2
Function-3
Local Data
Local Data
Local Data
Object B
Data
Functions
Object C
Data
Functions
Class
Object contains data, and code to manipulate that 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.
Data Encapsulation
The wrapping up of data and functions into a single unit is known as encapsulation.
The data is not accessible to the outside world, only those function which are wrapped in the
can access it.
These functions provide the interface between the objects data and the program.
This insulation of the data from direct access by the program is called data hiding or
information hiding.
Data Abstraction
Abstraction refers to the act of representing essential features without including the
background details or explanations.
Since classes use the concept of data abstraction, they are known as Abstract Data Types
(ADT).
Inheritance
Inheritance is the process by which objects of one class acquire the properties of objects of
another class.
In OOP, the concept of inheritance provides the idea of reusability. This means we can add
additional features to an existing class without modifying it.
Polymorphism
Polymorphism, a Greek term means to ability to take more than one form.
An operation may exhibits different behaviors in different instances. The behavior depends
upon the type of data used in the operation.
For example consider the operation of addition for two numbers; the operation will generate a
sum. If the operands are string then the operation would produce a third string by
concatenation.
The process of making an operator to exhibit different behavior in different instances is known
operator overloading.
Shape
Draw ()
Circle Object
Box Object
Triangle Object
Draw (circle)
Draw (Box)
Draw (Triangle)
An Output statement is used to print the output on computer screen. cout is an output statement.
cout<<Srinix College of Engineering; prints Srinix College of Engineering on computer screen.
cout<<x; print x on computer screen.
cout<<x; prints value of x on computer screen.
cout<<\n; takes the cursor to a newline.
cout<< endl; takes the cursor to a newline. We can use endl (a manipulator) instead of \n.
<< (two "less than" signs) is called insertion operator.
An Input statement is used to take input from the keyboard. cin is an input statement.
cin>>x; takes the value of x from keyboard.
cin>>x>>y; takes value of x and y from the keyboard.
Program 1.1 WAP to accept an integer from the keyboard and print the number when it is
multiplied by 2.
Solution:
#include <iostream.h>
void main ()
{
int x;
cout << "Please enter an integer value: ";
cin >>x;
cout <<endl<< "Value you entered is " <<x;
cout << " and its double is " <<x*2 << ".\n";
}
Output:
Please enter an integer value:
5
Value you entered is 5 and its double is 10.
Operators
1. Arithmetic Operators (+, -, *, /, %)
The five arithmetical operations supported by the C language are:
Addition (+)
Subtraction (-)
Multiplication (*)
Division (/)
Modulo (%)
Operations of addition, subtraction, multiplication and division literally correspond with their respective
mathematical operators.
Division Rule
Integer/integer=integer
Integer/float=float
Float/integer=float
Float /float=float
Modular division
a>=b
a<b
Program 1.2
Solution:
#include <iostream.h>
void main ()
{
int a, b, p, q, r, s;
a = 10;
b=4;
p= a/b;
q= a*b;
r= a%b;
s= b%a;
cout<<p<<q<<r<<s;
}
Output:
2 40 2 4
Shorthand assignment (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)
When we want to modify the value of a variable by performing an operation on the value currently
stored in that variable we can use compound assignment operators:
value += increase; is equivalent to value = value + increase;
a -= 5; is equivalent to a = a - 5;
a /= b; is equivalent to a = a / b;
price *= units + 1; is equivalent to price = price * (units + 1); and the same for all other operators.
3. Relational and equality operators (==, !=, >, <, >=, <= )
In order to evaluate a comparison between two expressions we can use the relational and equality
operators. The result of a relational operation is a Boolean value that can only be true or false,
according to its Boolean result. We may want to compare two expressions, for example, to know if they
are equal or if one is greater than the other is. Here is a list of the relational and equality operators that
can be used in C++:
Here there are some examples:
(7 == 5) // evaluates to false.
(5 > 4) // evaluates to true.
(3 != 2) // evaluates to true.
(6 >= 6) // evaluates to true.
(5 < 5) // evaluates to false.
Of course, instead of using only numeric constants, we can use any valid expression, including variables.
Suppose that a=2, b=3 and c=6,
(a == 5) // evaluates to false since a is not equal to 5.
(a*b >= c) // evaluates to true since (2*3 >= 6) is true.
(b+4 > a*c) // evaluates to false since (3+4 > 2*6) is false.
((b=2) == a) // evaluates to true.
Important Tips!
Be careful! The operator = (one equal sign) is not the same as the operator == (two equal signs), the first
one is an assignment operator (assigns the value at its right to the variable at its left) and the other one
(==) is the equality operator that compares whether both expressions in the two sides of it are equal to
each other. Thus, in the last expression ((b=2) == a), we first assigned the value 2 to b and then we
compared it to a, that also stores the value 2, so the result of the operation is true.
b
True
False
True
False
a && b
True
False
False
False
The operator || corresponds with Boolean logical operation OR. This operation results true if either one
of its two operands is true, thus being false only when both operands are false themselves. Here are the
possible results of a || b:
a
True
True
False
False
b
True
False
True
False
a || b
True
True
True
False
For example:
( (5 == 5) && (3 > 6) ) // evaluates to false ( true && false ).
( (5 == 5) || (3 > 6) ) // evaluates to true ( true || false ).
are all equivalent in its functionality: the three of them increase by one the value of c.
A characteristic of this operator is that it can be used both as a prefix and as a suffix. That means that it
can be written either before the variable identifier (++a) or after it (a++). Although in simple expressions
like a++ or ++a both have exactly the same meaning, in other expressions in which the result of the
increase or decrease operation is evaluated as a value in an outer expression they may have an
important difference in their meaning: In the case that the increase operator is used as a prefix (++a) the
value is increased before the result of the expression is evaluated and therefore the increased value is
considered in the outer expression; in case that it is used as a suffix (a++) the value stored in a is
increased after being evaluated and therefore the value stored before the increase operation is
evaluated in the outer expression.
Pre First increment/decrement then assignment.
Post First assignment then increment/decrement.
Notice the difference:
Example 1
B=3;
A=++B;
Ans: A contains 4, B contains 4
Example 2
B=3;
A=B++;
Ans: A contains 3, B contains 4
In Example 1, B is increased before its value is assigned to A. While in Example 2, the value of B is
assigned to A and then B is increased.
6. Conditional operator ( ? : )
The conditional operator evaluates an expression returning a value if that expression is true and a
different one if the expression is evaluated as false. Its format is: condition ? result1 : result2. If
condition is true the expression will return result1, if it is not it will return result2.
7==5 ? 4 : 3 // returns 3, since 7 is not equal to 5.
7==5+2 ? 4 : 3 // returns 4, since 7 is equal to 5+2.
5>3 ? a : b // returns the value of a, since 5 is greater than 3.
a>b ? a : b // returns whichever is greater, a or b.
Program 1.3
Solution:
#include <iostream.h>
10
void main ()
{
int a,b,c;
a=2;
b=7;
c = (a>b) ? a : b;
cout<<c;
}
Output: 7
In this example a was 2 and b was 7, so the expression being evaluated (a>b) was not true, thus the first
value specified after the question mark was discarded in favor of the second value (the one after the
colon) which was b, with a value of 7.
7. Comma operator ( , )
The comma operator (,) is used to separate two or more expressions that are included where only one
expression is expected. When the set of expressions has to be evaluated for a value, only the rightmost
expression is considered.
For example, the following code:
a = (b=3, b+2); would first assign the value 3 to b, and then assign b+2 to variable a. So, at the end,
variable a would contain the value 5 while variable b would contain value 3.
9. sizeof ()
This operator accepts one parameter, which can be either a type or a variable itself and returns the size
in bytes of that type or object:
a = sizeof (char);
This will assign the value 1 to a because char takes 1 byte of memory. The value returned by sizeof is a
constant, so it is always determined before program execution.
11
Control Statements
A programming language uses control statements to cause the flow of execution to advance and
branch based on changes to the state of a program. C++ program control statements can be put into
the following categories: selection, iteration, and jump.
Selection statements allows program to choose different paths of execution based upon the
outcome of an expression or the state of a variable.
Iteration statements enable program execution to repeat one or more statements (that is,
iteration statements form loops).
Jump statements allows program to execute in a nonlinear fashion. All of Javas control
statements are examined here.
Selection Statements
1. if Statement
The if statement is C++s conditional branch statement. It can be used to route program execution
through two different paths. Here is the general form of the if statement:
if (condition)
{
statement1;
}
else
{
statement2;
}
Here, each statement may be a single statement or a compound statement enclosed in curly braces
(that is, a block). The condition is any expression that returns a boolean value. The else clause is
optional. The if statement works like this:
If the condition is true, then statement1 is executed. Otherwise, statement2 (if it exists) is executed.
Program 1.4
WAP to check whether a person is old or young. A person will be said old if his
age is above 35 and young if his age is below 35.
Solution:
#include<iostream.h>
void main()
{
int age;
cout<<Enter Age;
12
cin>>age;
if(age>=35)
cout<<"Old";
else
cout<<Young;
}
Output:
Enter age 39
Old
2. Nested ifs
A nested if is an if statement that is the target of another if or else. Nested ifs are very common in
programming. When you nest ifs, the main thing to remember is that an else statement always refers
to the nearest if statement that is within the same block as the else and that is not already associated
with an else.
3. The if-else-if Ladder
A common programming construct that is based upon a sequence of nested ifs is the if-else-if ladder. It
looks like this:
if (condition1)
statement1;
else if (condition2)
statement2;
..
..
else
statement3;
The if statements are executed from the top to down. As soon as one of the conditions controlling the if
is true, the statement associated with that if is executed, and the rest of the ladder is bypassed. If none
of the conditions is true, then the final else statement will be executed.
Program 1.5
mark given.
Solution:
#include<iostream.h>
void main()
{
int mark;
13
cout<<Enter mark;
cin>>mark;
if(mark>=60)
cout<<1st Division;
else if(mark>=50 && mark<60)
cout<<2nd Division;
else if(mark>=40 && mark<50)
cout<<3rd Division;
else
cout<<Fail;
}
Output:
Enter mark 87
1st Division
Switch Statements
The switch statement is C++s multi way branch statement. It provides an easy way to dispatch
execution to different parts of your code based on the value of an expression. As such, it often provides
a better alternative than a large series of if-else-if statements. Here is the general form of a switch
statement:
switch (expression)
{
case value1:
// statement sequence
break;
case value2:
// statement sequence
break;
...
case valueN:
// statement sequence
break;
default:
// default statement sequence
14
Program 1.6
Solution:
#include<iostream.h>
void main()
{
int i
for(int i=0; i<6; i++)
switch(i)
{
case 0:
cout<<i is zero.;
break;
case 1:
cout<<i is one.;
break;
case 2:
cout<<i is two.;
break;
case 3:
cout<<i is three.;
break;
default:
cout<<i is greater than 3.;
}
}
Output:
i is zero.
i is one.
i is two.
i is three.
i is greater than 3.
i is greater than 3.
Iteration Statements
15
C++s iteration statements are for, while, and do-while. These statements create what we commonly
call loops. As you probably know, a loop repeatedly executes the same set of instructions until a
termination condition is met.
1. while loop
The while loop is Javas most fundamental looping statement. It repeats a statement or block while its
controlling expression is true. Here is its general form:
initialization
while (condition)
{
// body of loop
Increment/ decrement
}
The condition can be any Boolean expression. The body of the loop will be executed as long as the
conditional expression is true. When condition becomes false, control passes to the next line of code
immediately following the loop. The curly braces are unnecessary if only a single statement is being
repeated.
Program 1.7
Write a program to print the message C++ is good 10 times using while loop.
Solution:
#include<iostream.h>
void main()
{
int n = 0;
while (n <10)
{
cout<<C++ is good;
n++;
}
}
2. do while Loop
If the conditional expression controlling a while loop is initially false, then the body of the loop will not
be executed at all. However, sometimes it is desirable to execute the body of a while loop at least once,
even if the conditional expression is false to begin with. The do-while loop always executes its body at
least once, because its conditional expression is at the bottom of the loop. Its general form is:
initialization
do
{
// body of loop
16
Increment/ decrement
} while (condition);
Program 1.8
Write a program to print the message C++ is good 10 times using do while loop.
Solution:
#include<iostream.h>
void main()
{
int n = 0;
do
{
cout<<C++ is good;
n++;
} while(n<9);
}
3. for loop
The general form of the for statement is:
for(initialization; condition; iteration)
{
// body
}
The for loop operates as follows:
When the loop first starts, the initialization portion of the loop is executed. Generally, this is an
expression that sets the value of the loop control variable, which acts as a counter that controls
the loop. It is important to understand that the initialization expression is only executed once.
Next, condition is evaluated. This must be a Boolean expression. It usually tests the loop control
variable against a target value. If this expression is true, then the body of the loop is executed. If
it is false, the loop terminates.
Next, the iteration portion of the loop is executed. This is usually an expression that increments
or decrements the loop control variable. The loop then iterates, first evaluating the conditional
expression, then executing the body of the loop, and then executing the iteration expression
with each pass. This process repeats until the controlling expression is false.
Program 1.9
Write a program to print the message C++is good 10 times using for loop.
Solution:
#include<iostream.h>
void main()
{
int n ;
17
Jump Statements
C++ offers following jump statements:
break statement: A break statement takes control out of the loop.
continue statement: A continue statement takes control to the beginning of the loop.
goto statement: A goto Statement take control to a desired line of a program.
Program 1.10
Solution:
#include<iostream.h>
void main()
{
int n, i;
cout<<Enter a number:;
cin>>n;
for(i=2; i<n; i++)
{
if(n%i==0)
{
cout<<Number is not Prime;
break;
}
}
if(i==n)
cout<<Number is Prime;
}
Output:
Enter a number 13
Number is Prime
Program 1.11
The marks obtained by a student in 5 different subjects are input through the
keyboard. The student gets a division as per the following rules:
Percentage above or equal to 60 - First division
Percentage between 50 and 59 - Second division
Percentage between 40 and 49 - Third division
Percentage less than 40 Fail. Write a program to calculate the division obtained by the student.
Solution:
#include<iostream.h>
18 C++ by Er Sourav Kumar Giri, E-mail:[email protected]
void main( )
{
int m1, m2, m3, m4, m5, per ;
cout<< "Enter marks in five subjects " ;
cin>>m1>>m2>>m3>>m4>>m5 ;
per = ( m1 + m2 + m3 + m4 + m5 ) / 5 ;
if ( per >= 60 )
{
cout<< "First division" ;
}
else if ( ( per >= 50 ) && ( per < 60 ) )
{
cout<< "Second division" ;
}
else if ( ( per >= 40 ) && ( per < 50 ) )
{
cout<<"Third division" ;
}
else
{
cout<< "Fail" ;
}
}
Output:
Enter marks in 5 subjects 65 65 65 60 70
First division
Program 1.12
Write a program to find the roots of a quadratic equation ax2+bx+c=0, where the
values of coefficient a, b and c are given from the keyboard.
Solution:
#include<iostream.h>
#include<math.h>
void main()
{
int a, b, c, d;
float r1, r2, x, y;
cout<<Enter the coefficients;
cin>>a>>b>>c;
d=(b*b) - (4*a*c);
if(d>0)
19
{
r1=(-b+pow(d,0.5))/2*a;
r2=(-b- pow(d,0.5))/2*a;
cout<<Roots are real and the roots are <<r1<< and <<r2;
}
else if(d==0)
{
r1=-b/2*a;
cout<< Roots are equal and the root is <<r1;
}
else
{
x=-b/2*a;
y =pow(-d,0.5)/2*a;
cout<<Roots are imaginary and the roots are<<endl;
cout<<x<<+i <<y<<endl;
cout<<x<<-i << y;
}
}
Output:
Enter the coefficients 1 -4 4
Roots are equal and the root is 2
Program 1.13
If the three sides of a triangle are entered through the keyboard, write a
program to check whether the triangle is isosceles, equilateral, scalene or right angled triangle.
Solution:
#include<iostream.h>
void main()
{
int a, b, c;
cout<<Enter 3 sides;
cin>>a>>b>>c;
if(a+b>c && b+c>a && c+a>b)
{
if((a*a+b*b)==c*c || (b*b+c*c)==a*a || (c*c+a*a)==b*b)
{
cout<<Right Angled;
}
else if( (a==b &&b!=c) || (b==c&&c!=a) || (c==a&&a!=b))
{
20
cout<<Isosceles;
}
else if(a==b && b==c)
{
cout<<Equilateral;
}
else
{
cout<<Any Valid Triangle;
}
}
else
{
cout<<Cannot form a valid triangle;
}
}
Program 1.14
Solution:
#include<iostream.h>
void main()
{
int i;
for(i=0; i<100 ; i+=2)
{
cout<< i<<\n;
}
}
Program
1.15
WAP
to
Solution:
#include<iostream.h>
void main()
{
int i, n, s=0;
cout<<Enter the value of n;
cin>>n;
for(i=1; i<=n; i++)
{
21
s=s+i;
}
cout<< s;
}
Program 1.16
Solution:
#include<iostream.h>
void main()
{
int i, n, f=1;
cout<<Enter the value of n;
cin>>n;
for(i=1; i<=n; i++)
{
f=f*i;
}
cout<<f;
}
Program 1.17
Solution:
#include<iostream.h>
void main()
{
int a, n, s=0;
cout<<Enter a number;
cin>>n;
while(n!=0)
{
a=n%10;
s=s+a;
n=n/10;
}
cout<<s;
}
Program 1.18
Solution:
22
#include<iostream.h>
void main()
{
int a, n, rn=0;
cout<<Enter a number;
cin>>n;
while(n!=0)
{
a=n%10;
rn=rn*10+a;
n=n/10;
}
cout<<rn;
}
Example 1.19
23
Example 1.20
Solution:
#include<iostream.h>
void main( )
{
int n, i ;
for(n=2; n<=500; n++)
{
for(i=2; i<=n-1; i++)
{
if ( n% i == 0 )
{
break ;
24
}
}
if ( i == n )
{
cout<<n<< "\t" ;
}
}
}
Array
Collection of similar data types stored in contiguous memory location is known as array.
Syntax is:Data_type array_name[size];
i.e. int a[20]; means a is an array which can hold 20 integers. char nm[16]; means nm is an array which
can hold 16 character. An array index always starts from 0 and index of last element is n-1, where n is
the size of the array.
In the above example:
a[0] is the first element.
a[1] is the second element.
And a[19] is the last element of the array a.
Structure
A structure is a collection of dissimilar data types.
struct book
{
char name ;
float price ;
int pages ;
};
struct book b1, b2, b3 ;
Here b1, b2 and b3 are structure variable of type book. And name, price and pages are called structure
members. To access a structure member we need dot(.) operator.
b1.name - name of book b1.
b1.price price of book b1.
b1.pages price of book b1.
25
Union
A union is a collection of dissimilar datatypes.
union book
{
char name ;
float price ;
int pages ;
};
unionbook b1, b2, b3 ;
Here b1, b2 and b3 are union variable of type book.
Here b1, b2 and b3 are union variable of type book. And name, price and pages are called union
members. To access a union member we need dot(.) operator.
b1.name - name of book b1.
b1.price price of book b1.
b1.pages price of book b1.
Union
1) Syntax:
union union_name
{
//Data types
}
2) In a union only one member can be used at a
time.
3) Union allocates the memory equal to the
maximum memory required by the member of
the union.
union example{
int x;
float y;
}
Here memory allocated is sizeof(y), because
size of float is more than size of integer.
Function
A function is a self-contained block of statements that perform a coherent task of some kind. Basically
a function consists of three parts:
26
Function Calling: A function gets called when the function name is followed by a semicolon.
Syntax is : function_name(list of arguments);
Example: sum(x,y); search(mark);
Function Definition: A function is defined when function name is followed by a pair of braces in
which one or more statements may be present.
Syntax is:
Return_type function_name(list of arguments with their types)
{
//Function Body
}
In call by value, value of the argument is passed during function calling. In call by reference
address of the argument is passed during function calling.
In call by value of actual arguments do not changes. But in call by reference value of actual
argument changes.
Memory can be saved if we call a function by reference.
Program 1.22
Write a program to swap two integers using call by value and call by
reference.
Solution:
Call by value
Call by refernece
#include<iostream.h>
void swap(int, int);
void main()
{
int x=5, y=7;
swap(x, y);
cout<<x<<y<<endl;
}
void swap(int a, int b)
{
int t=a;
a=b;
b=t;
cout<<a<<b;
#include<iostream.h>
void swap(int *, int *);
void main()
{
int x=5, y=7;
swap(&x, &y);
cout<<x<<y<<endl;
}
void swap(int *a, int *b)
{
int t=*a;
*a=*b;
*b=t;
cout<<*a<<*b;
27
Output:
5 7
7 5
Output:
7 5
7 5
Default arguments
28
// legal
// illegal
// illegal
// legal
Assignment-1
Short Type Questions
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
29
Chapter 2
protected:
Variable declaration/data members;
Function declaration/ member functions;
public:
Variable declaration/data members;
Function declaration/ member functions;
};
Points to remember!
The variables declared inside the class definition are known as data members and the functions
declared inside a class are known as member functions.
Wrapping of data and function and function into a single unit (i.e. class) is known as data
encapsulation.
By default the data members and member function of a class are private.
Private data members can be accessed by the functions that are wrapped inside the class.
Header files
Class definition
Member function definition
void main function
Program 2.1
Write a program to find sum of two integers using class and object.
Solution:
#include<iostream.h>
30
class Add
{
int x, y, z;
public:
void getdata()
{
cout<<Enter two numbers;
cin>>x>>y;
}
void calculate(void);
void display(void);
};
void Add :: calculate()
{
z=x+y;
}
void Add :: display()
{
cout<<z;
}
void main()
{
Add a;
a.getdata();
a.calculate();
a.display();
}
Output:
Enter two numbers 5 6
11
A member function can be defined:
(i)
(ii)
31
Here in the above example we are defining the member function getdata() inside the class
definition. And we are defining the member functions calculate() and display(), outside the class
definition using the scope resolution operator.
Here void Add :: calculate() means the scpoe of member function calculate() is inside the class
Add or we can say the function calculate() belongs to the class Add. :: is the scope resolution
operator which tells the scope of a member function.
We cannot directly call a function, we can call it using object (through . operator) of the class in
which the function is declared.
Write a program to add two time objects (in the form hh:mm).
Solution:
#include<iostream.h>
class time
{
int hours, minutes;
public:
void gettime(int h, int m)
{
hours=h;
minutes=m;
}
void sum(time, time);
void display(void);
};
void time :: sum (time t1, time t2)
{
minutes=t1.minutes+t2.minutes;
hours=minutes/60;
32
minutes=minutes%60;
hours=hours+t1.hours+t2.hours;
}
void time :: display()
{
cout<<hours<< : <<minutes<<endl;
}
void main()
{
time T1, T2, T3;
T1.gettime(2,45);
T2.gettime(3,30);
T3.sum(T1, T2);
T1.display();
T2.display();
cout<<"Addition of above two time is ";
T3.display();
}
Output:
2 : 45
3 : 15
Addition of above two time is 6:15
Array of object
Collection of similar types of object is known as array of objects.
Program 2.3
Write a program to input name and age of 5 employees and display them.
Solution:
#include<iostream.h>
class Employee
{
char name[30];
int age;
public:
void getdata(void);
void putdata(void);
};
33
25
27
23
26
32
Constructor
A constructor is a special member function whose task is to initialize the object of a class.
Its name is same as the class name.
A constructor does not have a return type.
34
A constructor is called or invoked when the object of its associated class is created.
It is called constructor because it constructs the values of data members of the class.
A constructor cannot be virtual (shall be discussed later on).
A constructor can be overloaded.
Default Constructor
Parameterized Constructor
Copy constructor
Default Constructor
The constructor which has no arguments is known as default constructor.
Program 2.4
Solution:
#include<iostream.h>
class Add
{
int x, y, z;
public:
Add();
void calculate(void);
void display(void);
// Default Constructor
};
Add::Add()
{
x=6;
y=5;
}
void Add :: calculate()
{
z=x+y;
}
void Add :: display()
{
cout<<z;
}
void main()
{
Add a;
a.calculate();
35
a.display();
}
Output:
11
Note: Here in the above program when the statement Add a; will execute (i.e. object is created), the
default constructor Add () will be called automatically and value of x and y will be set to 6 and 5
respectively.
Parameterized constructor
The constructor which takes some argument is known as parameterized constructor.
Program 2.5
36
Copy Constructor
The constructor which takes reference to its own class as argument is known as copy constructor.
Program 2.6
37
}
Add(Add &);
void calculate(void);
void display(void);
};
Add :: Add(Add &p)
{
x=p.x;
y=p.y;
cout<<Value of x and y for new object: <<x<< and <<y<<endl;
}
void Add :: calculate()
{
z=x+y;
}
void Add :: display()
{
cout<<z;
}
void main()
{
Add a(5, 6);
Add b(a);
b.calculate();
b.display();
}
Output:
Value of x and y for new object are 5 and 6
11
Note: Here in the above program when the statement Add a(5, 6); will execute (i.e. object creation), the
parameterized constructor Add (int, int) will be called automatically and value of x and y will be set to 5
and 6respectively. Now when the statement Add b(a) ; will execute, the copy constructor Add(Add& )
will be called and the content of object a will be copied into object b.
38
Destructor
Program 2.7
Demonstration of Destructor.
Solution:
#include<iostream.h>
class XYZ
{
int x;
public:
XYZ( );
~XYZ( );
void display(void);
};
XYZ::XYZ( )
{
x=9;
}
XYZ:: ~XYZ( )
{
cout<<Object is destroyed<<endl;
}
void XYZ::display()
{
cout<<x;
}
void main()
{
XYZ xyz;
xyz.display();
}
Output:
9
Object is destroyed.
39
Inline function
In C++, we can create short functions that are not actually called, rather their code is expanded in line at
the point of each invocation. This process is similar to using a function-like macro. To cause a function
to be expanded in line rather than called, precede its definition with the inline keyword.
A function which is expanded in a line when it is called is called inline function.
It executes faster than other member function.
It can be recursive.
Its body does not contain if else, switch, loop, goto statement.
The inline keyword is preceded by function definition.
Program 2.8
Solution:
#include<iostream.h>
inline float area(int);
void main()
{
int r;
cout<< Enter the Value of r: ;
cin>>r;
cout<< Area is: << area(r);
}
inline float area (int a)
{
return(3.14*a*a);
}
Output:
Enter the Value of r:
7
153.86
40
Friend Function
Program 2.9
Solution:
#include<iostream.h>
class Add
{
int x, y, z;
public:
Add(int, int);
friend int calculate(Add p);
};
Add :: Add(int a, int b)
{
x=a;
y=b;
}
int calculate(Add p)
{
return(p.x+p.y);
}
void main()
{
Add a(5, 6);
cout<<calculate(a);
}
Output:
11
Note: Here the function calculate () is called directly like normal function as it is declared as friend.
41
Friend Classes
It is possible for one class to be a friend of another class. When this is the case, the friend class and all of
its member functions have access to the private members defined within the other class.
#include <iostream.h>
class TwoValues
{
int a;
int b;
public:
TwoValues(int i, int j)
{
a = i;
b = j;
}
friend class Min;
};
class Min
{
public:
int min(TwoValues x);
};
int Min::min(TwoValues x)
{
return x.a < x.b ? x.a : x.b;
}
int main()
{
TwoValues ob(10, 20);
Min m;
cout << m.min(ob);
return 0;
}
Output:
10
Note: In this example, class Min has access to the private variables a and b declared within the
TwoValues class.
42
The data member of a class preceded by the keyword static is known as static member.
When we precede a member variable's declaration with static, we are telling the compiler that
only one copy of that variable will exist and that all objects of the class will share that variable.
Hence static variables are called class variables.
Unlike regular data members, individual copies of a static member variable are not made for
each object. No matter how many objects of a class are created, only one copy of a static data
member exists. Thus, all objects of that class use that same variable.
All static variables are initialized to zero before the first object is created.
Normal data members are called object variable but static data members are called class
variables.
Program 2.11
Solution:
#include<iostream.h>
class A
{
int p;
static int q;
public:
A();
void incr(void);
void display(void);
};
A :: A()
{
p=5;
}
int A:: q=10;
void A:: incr()
{
p++;
q++;
}
void A:: display()
{
cout<<p<<\t<<q<<endl;
}
void main()
43
{
A a1, a2, a3;
a1.incr();
a1.display();
a2.incr();
a2.display();
a3.incr();
a3.display();
}
Output:
6
11
6
12
6
13
Note: Here p is a normal variable, whose value is 5 for all 3 objects a1, a2 and a3 (For each object,
separate copy of p exists). But q is static variable or member, whose initial value is 10 and a single copy
of q exists for all the objects.
A static function can have access to only other static members (functions or variables) declared
in the same class. (Of course, global functions and data may be accessed by static member
functions.)
It is accessed by class name and not by objects name i.e. class-name::function-name;
The function name is preceded by the keyword static.
A static member function does not have this pointer.
There cannot be a static and a non-static version of the same function.
A static member function may not be virtual.
Finally, they cannot be declared as const or volatile.
Program 2.12
Solution:
#include<iostream.h>
class ABC
{
public:
static int add(int, int);
};
int ABC:: add(int a, int b)
{
44
return(a+b);
}
void main()
{
ABC abc;
int res;
res=ABC :: add(30, 40);
cout<<res;
}
Output:
70
45
Assignment 2
Short Type Questions
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
46
Find Output:
1. #include<iostream.h>
int x=5;
void main()
{
int x=4;
cout<<x<<::x;
}
2. #include<iostream.h>
void main()
{
int a=2, b=1;
char x=1, y=0;
if(a, b, x, y)
cout<<Congratulations!!;
}
47
3. class F
{
int p;
public:
friend void print(){ }
};
void main()
{
print();
}
4. class M
{
char nm[50];
public:
show();
};
3. #include<iostream.h>
int x=5;
void main()
{
(5/2)? cout<<Hi:cout<<Hello;
}
4. #include<iostream.h>
void main()
{
int a, b;
a=(b=7, b+2);
cout<<a;
}
Chapter 3
Inheritance
It is the process by which object of one class acquires the properties of object of another class. The class
from which properties are inherited is called base class and the class to which properties are inherited is
called derived class. Inheritance can be broadly classified into:
Single Inheritance
Multiple Inheritance
Multilevel Inheritance
Hierarchical Inheritance
Hybrid Inheritance
When the access specifier for a base class is public, all public members of the base become
public members of the derived class, and all protected members of the base become protected
members of the derived class.
When the base class is inherited by using the private access specifier, all public and protected
members of the base class become private members of the derived class.
When a base class' access specifier is protected, public and protected members of the base
become protected members of the derived class.
In all cases, the base's private elements remain private to the base and are not accessible by members
of the derived class.
48
Single Inheritance
In a single inheritance the derived class is derived from a single base class.
A
B
(Single inheritance)
Program 4.1
Solution:
#include <iostream.h>
class A
{
int i, j;
public:
void set(int a, int b)
{
i=a; j=b;
}
void show()
{
cout << i << " " << j << "\n";
}
};
class B : public A
{
int k;
public:
B(int x)
{
k=x;
}
void showk()
{
cout << k << "\n";
}
};
49
void main()
{
B b(3);
b.set(1, 2);
b.show();
b.showk();
}
Output:
12
3
Note: Here all public and protected members of the base class become private members of the derived
class. So object of derived class cannot directly access the member function and data members of the
base class.
Program 4.2
Solution:
#include <iostream.h>
class A
{
int i, j;
public:
void set(int a, int b)
{
i=a; j=b;
}
void show()
{
cout << i << " " << j << "\n";
}
};
class B : private A
{
int k;
public:
B(int x)
{
k=x;
}
void showk()
{
cout << k << "\n";
}
50
};
void main()
{
B b(3);
b.set(1, 2);
b.show(); //******Error******
}
How to access the private data member of base class in derived class?
Private data members of base class can be accessed by derived class by using public member
function/methods of the base class.
Multiple Inheritance
In multiple inheritance derived class is derived from more than one base class.
(Multiple Inheritance)
Multilevel Inheritance
In multilevel inheritance class B is derived from a class A and a class C is derived from the class B.
Syntax:
class base-class-name1
{
Data members
Member functions
};
class derived-class-name : visibility mode base-class-name
{
Data members
Member functions
51
};
class derived-class-name1: visibility mode derived-class-name
{
Data members
Member functions
};
Note: visibility mode can be either private, public or protected
C
(Multilevel inheritance)
Hierarchical Inheritance
In hierarchical inheritance several classes can be derived from a single base class
Syntax:
class base-class-name
{
Data members
Member functions
};
class derived-class-name1 : visibility mode base-class-name
{
Data members
Member functions
};
52
(Hierarchical inheritance)
Hybrid inheritance
It is the mixture of one or more above inheritance.
A
53
Output:
Constructing base
Constructing derived
Destructing derived
Destructing base
Note: In the above program, first base's constructor is executed followed by derived's. Next (because ob
is immediately destroyed in this program), derived's destructor is called, followed by base's.
54
Program 4.5
Solution:
#include <iostream.h>
class base
{
public:
base()
{
cout << "Constructing base\n";
}
~base()
{
cout << "Destructing base\n";
}
};
class derived1 : public base
{
public:
derived1()
{
cout << "Constructing derived1\n";
}
~derived1()
{
cout << "Destructing derived1\n";
}
};
class derived2: public derived1
{
public:
derived2()
{
cout << "Constructing derived2\n";
}
~derived2()
{
cout << "Destructing derived2\n";
}
};
void main()
{
55
derived2 ob;
}
Output:
Constructing base
Constructing derived1
Constructing derived2
Destructing derived2
Destructing derived1
Destructing base
Program 4.6
Solution:
#include <iostream.h>
class base1
{
public:
base1()
{
cout << "Constructing base1\n";
}
~base1()
{
cout << "Destructing base1\n";
}
};
class base2
{
public:
base2()
{
cout << "Constructing base2\n";
}
~base2()
{
cout << "Destructing base2\n";
}
};
class derived: public base1, public base2
{
public:
56
derived()
{
cout << "Constructing derived\n";
}
~derived()
{
cout << "Destructing derived\n";
}
};
void main()
{
derived ob;
}
Output:
Constructing base1
Constructing base2
Constructing derived
Destructing derived
Destructing base2
Destructing base1
Note: In the above program, constructors are called in order of derivation, left to right, as specified in
derived's inheritance list. Destructors are called in reverse order, right to left.
Here, base1 through baseN are the names of the base classes inherited by the derived class. Notice that
a colon separates the derived class' constructor declaration from the base-class specifications, and that
the base-class specifications are separated from each other by commas, in the case of multiple base
classes.
57
Program 4.7
Solution:
#include <iostream.h>
class base
{
protected:
int i;
public:
base(int x)
{
i=x; cout << "Constructing base\n";
}
~base()
{
cout << "Destructing base\n";
}
};
class derived: public base
{
int j;
public:
derived(int x, int y): base(y)
{
j=x; cout << "Constructing derived\n";
}
~derived()
{
cout << "Destructing derived\n";
}
void show()
{
cout << i << " " << j << "\n";
}
};
void main()
{
derived ob(3, 4);
ob.show();
}
58
GRAND PARENT
int i
PARENT 2
PARENT1
int j
int i
int k
int i
CHILD
59
This is ambiguity problem. In CHILD class have two copies of Base class. There are two duplicate copies
of int i of base class. One copy through PARENT1 and another copy from PARENT2.
This problem is also called as DIAMOND Problem.
60
As the comments in the program indicate, both derived1 and derived2 inherit base. However, derived3
inherits both derived1 and derived2. This means that there are two copies of base present in an object
of type derived3. Therefore, in an expression like
ob.i = 10; which i is being referred to, the one in derived1 or the one in derived2? Because there are two
copies of base present in object ob, there are two ob.is! As we can see, the statement is inherently
ambiguous.
There are two ways to remedy the preceding program. The first is to apply the scope resolution
operator to i and manually select one i. The second is to use virtual base class.
61
public:
int j;
};
class derived2 : virtual public base
{
public:
int k;
};
class derived3 : public derived1, public derived2
{
public:
int sum;
};
void main()
{
derived3 ob;
ob.i = 10; // now unambiguous
ob.j = 20;
ob.k = 30;
ob.sum = ob.i + ob.j + ob.k; // unambiguous
cout << ob.i << " "; // unambiguous
cout << ob.j << " " << ob.k << " ";
cout << ob.sum;
}
As we can see, the keyword virtual precedes the rest of the inherited class specification. Now that both
derived1 and derived2 have inherited base as virtual, any multiple inheritance involving them will cause
only one copy of base to be present. Therefore, in derived3, there is only one copy of base and ob.i = 10
is perfectly valid and unambiguous.
62
Assignment 3
Short Type Questions
1.
2.
3.
4.
5.
Define Inheritance.
Write any two advantages of inheritance.
List various types of inheritances.
Define virtual base class.
How do the properties of the following two derived classes differ?
class X: private Y { //.};
class A: proctected B { //.};
6. Private attributes cant be inherited. State a remedy for this problem so that attributes of a
class behave like private attributes but can be inherited. Explain with an example.
63
Chapter 4
Polymorphism and Virtual Functions
Polymorphism means one name, multiple forms.
For example, the + (plus) operator in C++ will behave different for different data types:
4 + 5 <-- integer addition
3.14 + 2.0 <-- floating point addition
Good + "Boy <-- string concatenation
(ii)
Function Overloading
It is the process by which a single function can perform different task, depending upon no of
parameters and types of parameters.
Solution:
#include <iostream.h>
float area(int);
int area(int, int);
void main( )
{
int r, l, b;
cout << Enter the Value of r, l & b: ;
cin>>r>>l>>b;
cout<< Area of circle is <<area(r)<<endl;
cout<< Area of rectangle is <<area(l,b);
}
float area(int a)
64
{
return (3.14*a*a);
}
int area(int a, int b)
{
return (a*b);
}
Output:
Enter the Value of r, l & b:
786
Area of circle is 153.86
Area of circle is 48
Object Slicing
In object-oriented programming, a derived class typically inherits its base class by defining additional
member variables. If a base class instance is assigned its value from a derived class instance, member
variables defined in the derived class cannot be copied, since the base class has no place to store them.
This is a natural and unavoidable consequence of assignment by value from derived class objects. The
65
term object slicing is sometimes used to refer to this aspect of assignment by value to a base class
instance.
Object Slicing occurs when object of a derived class is assigned to an object of a base class, thereby
losing part of the information - some of it is sliced" away.
Example:
class A
{
int x;
};
class B : public A
{
int y;
};
So an object of type B has two data members, x and y Then if we are writing this code:
B b;
A a = b;
Then the information in b about member y will be lost in a.
Program 4.2
Solution:
#include<iostream.h>
class B
{
public:
void show()
{
cout<<"I am in base show"<<endl;
}
};
class D:public B
{
public:
void show()
{
cout<<"I am in derived show"<<endl;
66
}
};
void main()
{
B b, *bp;
D d;
bp=&b;
bp->show();
bp=&d;
bp->show();
}
Output:
I am in base show
I am in base show
Note: Here the base version of function show () will work as it overrides the derived version of show ().
A virtual function is a member function that is declared within a base class and redefined by a derived
class. To create a virtual function, precede the function's declaration in the base class with the keyword
virtual. When a class containing a virtual function is inherited, the derived class redefines the virtual
function to fit its own needs. In essence, virtual functions implement the "one interface, multiple
methods" philosophy that underlies polymorphism. The virtual function within the base class defines the
form of the interface to that function. Each redefinition of the virtual function by a derived class
implements its operation as it relates specifically to the derived class. That is, the redefinition creates a
specific method.
Program 4.3
Solution:
#include<iostream.h>
class B
{
public:
virtual void show()
{
cout<<"I am in base show"<<endl;
}
};
class D:public B
{
public:
67
void show()
{
cout<<"I am in derived show"<<endl;
}
};
void main()
{
B b, *bp;
D d;
bp=&b;
bp->show();
bp=&d;
bp->show();
}
Output:
I am in base show
I am in derived show
Important Tips!
A base pointer can be made to point to any number of derived objects, it cannot access the members
defined by a derived class. It can access only the members which are common to the base class. If a
same function is present in both base and derived class, always base version of the function is called
when we access the function using base pointer (no matters whether it points to base class or derived
class). Derived version of the function can be called by making the function (having same name) as
virtual. This is also called function overriding because function in the base class is overridden by the
function in the derived class.
Remember!
When a virtual function is inherited, its virtual nature is also inherited. This means that when a derived
class that has inherited a virtual function is itself used as a base class for another derived class, the
virtual function can still be overridden.
68
When a virtual function is made pure, any derived class must provide its own definition. If the derived
class fails to override the pure virtual function, a compile-time error will result. Hence definition for pure
virtual function must be there in the derived class.
Abstract Classes
A class that contains at least one pure virtual function is said to be abstract. Because an abstract class
contains one or more functions for which there is no definition (that is, a pure virtual function), no
objects of an abstract class may be created.
Instead, an abstract class constitutes an incomplete type that is used as a foundation for derived
classes. Although we cannot create objects of an abstract class, we can create pointers and references
to an abstract class. This allows abstract classes to support run-time polymorphism, which relies upon
base-class pointers and references to select the proper virtual function.
Program 4.4
Create an abstract class called Shape which contains a pure virtual function called
find_vol() and a protected attribute named as volume. Create two new derived classes from the
above class named as Cube and Sphere having double type attribute named as side and radius
respectively. Implement dynamic polymorphism to find out volume of a cube and a sphere. Also
display the result.
[BPUT 2010]
Solution:
#include<iostream.h>
class Shape
{
protected:
double volume;
public:
virtual void find_vol()=0;
};
class Cube: public Shape
{
protected:
double side;
public:
Cube();
void find_vol();
};
class Sphere: public Shape
{
protected:
double radius;
public:
69
Sphere();
void find_vol();
};
Cube::Cube()
{
cout<<Enter side of the Cube:<<endl;
cin>>side;
}
Sphere::Sphere ()
{
cout<<Enter radius of the sphere:<<endl;
cin>>radius;
}
void Cube:: find_vol()
{
volume=side*side*side;
cout<<Volume of Cube is: <<volume<<endl;
}
void Sphere:: find_vol()
{
volume=(4/3)*3.14*radius*radius*radius;
cout<<Volume of sphere is: <<volume;
}
void main()
{
Shape *ptr;
Cube cube;
Sphere sphere;
ptr=&cube;
ptr->find_vol();
ptr=&sphere;
ptr->find_vol();
}
Output:
Enter side of the Cube:
3
Enter radius of the sphere:
4
70
71
Assignment 4
72
Chapter 5
Operator Overloading
this Pointer
Every object in C++ has access to its own address through an important pointer called this pointer. The
this pointer is an implicit parameter to all member functions. Therefore, inside a member function, this
may be used to refer to the invoking object.
Friend functions do not have a this pointer, because friends are not members of a class. Only non static
member functions have a this pointer.
Program 5.1
Solution:
#include <iostream.h>
class Box
{
private:
double length;
double breadth;
double height;
public:
Box(double l=2.0, double b=2.0, double h=2.0)
{
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
}
73
double Volume()
{
return (length * breadth * height);
}
int compare(Box box)
{
return (this->Volume() > box.Volume());
}
};
void main(void)
{
Box Box1(3.3, 1.2, 1.5);
Box Box2(8.5, 6.0, 2.0);
if(Box1.compare(Box2))
{
cout << "Box2 is smaller than Box1" <<endl;
}
else
{
cout << "Box2 is equal to or larger than Box1" <<endl;
}
}
Output:
Constructor called.
Constructor called.
Box2 is equal to or larger than Box1
Overloading Operators
A member operator function takes this general form:
return_type operator symbol(arg-list)
{
// operations
}
Often, operator functions return an object of the class they operate on, but return_type can be any
valid type(int, char, float, void etc). When you create an operator function, substitute the operator for
the symbol. For example, if you are overloading the / operator, use operator/. When you are
overloading a unary operator, arg-list will be empty. When you are overloading binary operators, arglist will contain one parameter.
74
Solution:
#include<iostream.h>
class A
{
int n;
public:
void getdata( );
void operator ++( );
void display( );
};
void A::getdata( )
{
cout<<Enter a number;
cin>>n;
}
void A::operator ++( )
{
n=n+1;
}
void A::display( )
{
cout<<n;
}
void main()
{
A a;
a.getdata();
a++;
a.display();
75
}
Output:
Enter a number
5
6
Program 5.3
Solution:
#include<iostream.h>
class A
{
int n;
public:
void getdata( );
friend void operator ++( A &);
void display( );
};
void A::getdata( )
{
cout<<Enter a number;
cin>>n;
}
void operator ++(A x)
{
x.n=x.n+1;
}
void A::display( )
{
cout<<n;
}
void main()
{
A a;
a.getdata();
a++;
a.display();
}
Output:
Enter a number
76
5
6
Program 5.4
77
Output:
2.5+ j3.4
4.2+ j6.5
6.7+ j9.9
Note: As you can see, operator+ () has only one parameter even though it overloads the binary +
operator. (You might expect two parameters corresponding to the two operands of a binary operator.)
The reason that operator+ () takes only one parameter is that the operand on the left side of the + is
passed implicitly to the function through the this pointer. The operand on the right is passed in the
parameter c. The fact that the left operand is passed using this also implies one important point: When
binary operators are overloaded, it is the object on the left that generates the call to the operator
function.
The statement c3=c1+c2; is same as c1.operator+(c2).
Program 5.5
78
{
cout<<real<< +j<<img<<\n;
}
void main()
{
Complex c1(2.5, 3.4), c2(4.2, 6.5), c3;
c3=c1+c2;
c1.display();
c2.display();
c3.display();
}
Output:
2.5+ j3.4
4.2+ j6.5
6.7+ j9.9
Program 5.5
Suppose there is a class called X with two double type attributes. Write a C++
program to create two objects named ob 1 and ob 2 of the above class and overload the binary ==
operator to perform the following operation within main():
if(ob 1== ob 2)
cout<<Objects are same<<endl;
else
cout<<Objects are different<<endl;
[BPUT 2010]
Solution:
#include<iostream.h>
class X
{
double d1, d2;
public:
X(double, double);
int operator==(X);
void display( );
};
X::X(double x, double y )
{
d1=x;
d2=y;
}
int X:: operator==(X p)
79
{
if(d1==p.d1 &&d2==p.d2)
return 1;
else
return 0;
}
void main()
{
X ob1(2.5, 3.4), ob2(2.5, 3.0);
if(ob 1== ob 2)
cout<<Objects are same<<endl;
else
cout<<Objects are different<<endl;
}
80
Assignment 5
1. Create a class complex with real and imaginary parts as member variables, member function
get () and disp () to input and display a complex number respectively. Write a program using the
above class to overload + and operators to perform addition and subtraction of two complex
numbers.
2. Write a program in C++ to overload subscript [] operator.
3. Define a class called Increment; the class contains one integer data member. Overload the
object of the class for both pre-increment and post-increment operator.
4. Write a program to compare two strings by overloading == operator.
5. Write a program to add two string using + operator overloading.
6. Write a program to overload new and delete operator.
7. Write an appropriate C++ code showing ambiguity resolving mechanism where a class attribute
has same name as that of a local parameter of a member by using this pointer.
8. Write a program to overload == operator to check whether two circles are equal or not. (Two
circles are said to be equal if their radius is same and center has same coordinate)
9. Write a program to overload new and delete operator in C++.
10. Write a program to overload == operator to check whether two strings are equal or not.
81
Chapter 6
Exception Handling
Two common types of error in a program are:
1) Syntax error (arises due to missing semicolon, comma, and wrong prog. constructs etc)
2) Logical error (wrong understanding of the problem or wrong procedure to get the solution)
Exceptions
Exceptions are the errors occurred during a program execution. Exceptions are of two types:
C++ exception handling mechanism is basically built upon three keywords namely, try, throw
and catch.
Try block hold a block of statements which may generate an exception.
When an exception is detected, it is thrown using a throw statement in the try block.
Try block
Detects and throws
exception
Catch block
Catches and handles the
exception
82
.
catch (type2 arg)
{
/* catch block*/
}
The exception handling mechanism is made up of the following elements:
try blocks
catch blocks
throw expressions
Write a program to find x/y, where x and y are given from the keyboard and
both are integers.
Program 7.1
Solution:
#include<iostream.h>
void main()
{
int x, y;
cout<<enter two number<<endl;
cin>>x>>y;
try
{
if(y!=0)
{
z=x/y;
cout<<endl<<z;
}
else
{
throw(y);
}
}
catch(int y)
{
cout<<exception occurred: y=<<y<<endl;
}
}
Output:
Enter two number
60
exception occurred:y=0
83
A try block can be localized to a function. When this is the case, each time the function is entered, the
exception handling relative to that function is reset. For example, examine this program.
Program 7.2
#include <iostream.h>
void Xhandler(int test)
{
try
{
if(test) throw test;
}
catch(int i)
{
cout << "Caught Exception #: " << i << '\n';
}
}
void main()
{
cout << "Start\n";
Xhandler(1);
Xhandler(2);
Xhandler(0);
Xhandler(3);
cout << "End";
}
Output:
Start
Caught Exception #: 1
Caught Exception #: 2
Caught Exception #: 3
End
As you can see, three exceptions are thrown. After each exception, the function returns. When the
function is called again, the exception handling is reset.
It is important to understand that the code associated with a catch statement will be executed only if it
catches an exception. Otherwise, execution simply bypasses the catch altogether. (That is, execution
never flows into a catch statement.) For example, in the following program, no exception is thrown, so
the catch statement does not execute.
#include <iostream.h>
void main()
84 C++ by Er Sourav Kumar Giri, E-mail:[email protected]
{
cout << "Start\n";
try
{
cout << "Inside try block\n";
cout << "Still inside try block\n";
}
catch (int i)
{
cout << "Caught an exception -- value is: ";
cout << i << "\n";
}
cout << "End";
}
Output:
Start
Inside try block
Still inside try block
End
85
}
};
void main()
{
int i;
try {
cout << "Enter a positive number: ";
cin >> i;
if(i<0)
throw MyException("Not Positive", i);
}
catch (MyException e) { // catch an error
cout << e.str_what << ": ";
cout << e.what << "\n";
}
}
Output:
Enter a positive number: -4
Not Positive: -4
The program prompts the user for a positive number. If a negative number is entered, an object of the
class MyException is created that describes the error. Thus, MyException encapsulates information
about the error. This information is then used by the exception handler. In general, you will want to
create exception classes that will encapsulate information about an error to enable the exception
handler to respond effectively.
Output:
Start
Caught Exception #: 1
Caught Exception #: 2
Caught a string: Value is zero
Caught Exception #: 3
End
As you can see, each catch statement responds only to its own type.
87
void main()
{
D derived;
try
{
throw derived;
}
catch(B b)
{
cout << "Caught a base class.\n";
}
catch(D d)
{
cout << "This won't execute.\n";
}
}
Here, because derived is an object that has B as a base class, it will be caught by the first catch clause
and the second clause will never execute. Some compilers will flag this condition with a warning
message. Others may issue an error. Either way, to fix this condition, reverse the order of the catch
clauses.
88
}
catch(...)
{
cout << "Caught One!\n";
}
}
void main()
{
cout << "Start\n";
Xhandler(0);
Xhandler(1);
Xhandler(2);
cout << "End";
}
Output:
Start
Caught One!
Caught One!
Caught One!
End
Rethrowing an Exception
If you wish to rethrow an expression from within an exception handler, you may do so by calling throw,
by itself, with no exception. This causes the current exception to be passed on to an outer try/catch
sequence. The most likely reason for doing so is to allow multiple handlers access to the exception. For
example, perhaps one exception handler manages one aspect of an exception and a second handler
copes with another. An exception can only be rethrown from within a catch block (or from any function
called from within that block). When you rethrow an exception, it will not be recaught by the same
catch statement. It will propagate outward to the next catch statement. The following program
illustrates rethrowing an exception, in this case a char * exception.
Program 7.7
#include <iostream.h>
void Xhandler()
{
try
{
throw "hello"; // throw a char *
}
catch(const char *)
{
cout << "Caught char * inside Xhandler\n";
throw ; // rethrow char * out of function
89
}
}
void main()
{
cout << "Start\n";
try
{
Xhandler();
}
catch(const char *)
{
cout << "Caught char * inside main\n";
}
cout << "End";
}
Output:
Start
Caught char * inside Xhandler
Caught char * inside main
end
90
Assignment 6
Short Type Question
1. What is exception?
2. Differentiate between syntax error and logical error.
Long Type Questions
1. What is an exception? Describe the mechanism of exception handling with suitable example?
2. What is a generic catch block? What are the restrictions while using a generic catch block?
Explain with an example.
91
Chapter 7
Dynamic Memory Management
There are two ways to allocate memory:
(i)
Static memory allocation
(ii)
Dynamic memory allocation
Solution:
#include <iostream.h>
void main()
{
int *p;
try
{
p = new int;
}
catch (bad_alloc xa)
{
cout << "Allocation Failure\n";
92
return 1;
}
*p = 100;
cout << "At " << p << " ";
cout << "is the value " << *p << "\n";
delete p;
}
This program assigns to p an address in the heap that is large enough to hold an integer. It then assigns
that memory the value 100 and displays the contents of the memory on the screen. Finally, it frees the
dynamically allocated memory. Remember, if your compiler implements new such that it returns null
on failure, you must change the preceding program appropriately.The delete operator must be used
only with a valid pointer previously allocated by using new. Using any other type of pointer with delete
is undefined and will almost certainly cause serious problems, such as a system crash.
Object Copying
An object copy is an action in computing where a data object has its attributes copied to another object
of the same data type. An object is a composite data type in object-oriented programming languages.
The copying of data is one of the most common procedures that occur in computer programs. An
object may be copied to reuse all or part of its data in a new context.
93
Methods of copying
The design goal of most objects is to give the semblance of being made out of one monolithic block
even though most are not. As objects are made up of several different parts, copying becomes
nontrivial. Several strategies exist to attack this problem.
Consider two objects, A and B, which each refer to two memory blocks xi and yi (i = 1, 2,...). Think of A
and B as strings and of xi and yi (i = 1, 2,...) as the characters they contain. There are different strategies
for copying A into B.
Shallow copy
One method of copying an object is the shallow copy. In the process of shallow copying A, B will copy
all of A's field values. If the field value is a memory address it copies the memory address, and if the
field value is a primitive type it copies the value of the primitive type.
The disadvantage is if you modify the memory address that one of B's fields point to, you are also
modifying what A's fields point to.
Deep copy
A deep copy
completed.
having
been
An alternative is a deep copy. Here the data is actually copied over. The result is different from the
result a shallow copy gives. The advantage is that A and B do not depend on each other but at the cost
of a slower and more expensive copy.
94
Lazy copy
A lazy copy is a combination of both strategies above. When initially copying an object, a (fast) shallow
copy is used. A counter is also used to track how many objects share the data. When the program wants
to modify an object, it can determine if the data is shared (by examining the counter) and can do a deep
copy if necessary.
Lazy copy looks to the outside just as a deep copy but takes advantage of the speed of a shallow copy
whenever possible. The downsides are rather high but constant base costs because of the counter.
Also, in certain situations, circular references can cause problems. Lazy copy is related to copy-onwrite.
Copy Constructor
When one object is used to initialize another, C++ performs a bitwise copy. That is, an identical copy of
the initializing object is created in the target object. Although this is perfectly adequate for many
casesand generally exactly what you want to happenthere are situations in which a bitwise copy
should not be used. One of the most common is when an object allocates memory when it is created.
For example, assume a class called MyClass that allocates memory for each object when it is created,
and an object A of that class. This means that A has already allocated its memory. Further, assume that
A is used to initialize B, as shown here:
MyClass B= A;
If a bitwise copy is performed, then B will be an exact copy of A. This means that B will be using the
same piece of allocated memory that A is using, instead of allocating its own. Clearly, this is not the
desired outcome. For example, if MyClass includes a destructor that frees the memory, then the same
piece of memory will be freed twice when A and B are destroyed!
The same type of problem can occur in two additional ways: first, when a copy of an object is made
when it is passed as an argument to a function; second, when a temporary object is created as a return
value from a function. Remember, temporary objects are automatically created to hold the return value
of a function and they may also be created in certain other circumstances .To solve the type of problem
just described, C++ allows you to create a copy constructor, which the compiler uses when one object
initializes another. When a copy constructor exists, the default, bitwise copy is bypassed. The most
common general form of a copy constructor is
classname (const classname &o)
{
// body of constructor
}
Here, o is a reference to the object on the right side of the initialization. It is permissible for a copy
constructor to have additional parameters as long as they have default arguments defined for them.
However, in all cases the first parameter must be a reference to the object doing the initializing.
95
It is important to understand that C++ defines two distinct types of situations in which the value of one
object is given to another. The first is assignment. The second is initialization, which can occur any of
three ways:
When one object explicitly initializes another, such as in a declaration
When a copy of an object is made to be passed to a function
When a temporary object is generated (most commonly, as a return value)
The copy constructor applies only to initializations. For example, assuming a class
called myclass, and that y is an object of type myclass, each of the following statements
involves initialization.
myclass x = y; // y explicitly initializing x
func(y); // y passed as a parameter
y = func(); // y receiving a temporary, return object.
Virtual destructor
In C++ a destructor is generally used to deallocate memory and do some other cleanup for a class object
and its class members whenever an object is destroyed. Destructors are distinguished by the tilde, the
~ that appears in front of the destructor name. In order to define a virtual destructor, all you have to do
is simply add the keyword virtual before the tilde symbol.
The need for virtual destructors in C++ is best illustrated by some examples. Lets start by going
through an example that does not use virtual destructors, and then we will go through an example that
does use virtual destructors. Once you see the difference, you will understand why virtual destructors
are needed. Take a look at the code below to start out:
Program 7.2
96
{
Base *basePtr = new Derive();
delete basePtr;
}
Output:
Constructing Base
Constructing Derive
Destroying Base
Note: Based on the output above, we can see that the constructors get called in the appropriate order
when we create the Derive class object pointer in the main function. But there is a major problem with
the code above: the destructor for the "Derive" class does not get called at all when we delete basePtr.
So, how can we fix this problem?
Well, what we can do is make the base class destructor virtual, and that will ensure that the destructor
for any class that derives from Base (in our case, its the "Derive" class) will be called.
Program 7.3 Example with a Virtual Destructor:
So, the only thing we will need to change is the destructor in the Base class and heres what it will look
like note that we highlighted the part of the code where the virtual keyword has been added in bold:
class Base
{
public:
Base()
{
cout<<"Constructing Base";
}
virtual ~Base()
{
cout<<"Destroying Base";
}
};
Output:
Constructing Base
Constructing Derive
Destroying Derive
Destroying Base
Note: Here the derived class destructor will be called before the base class. So, now youve seen why
we need virtual destructors and also how they work. One important design paradigm of class design is
that if a class has one or more virtual functions, then that class should also have a virtual destructor.
97
Assignment 7
98
Chapter 8
Templates
99
Output:
20
10
23.2
10.1
z
x
Note: The line:
template <class T> void swap (T p, T q) tells the compiler two things: that a template is being created
and that a generic definition is beginning. Here, T is a generic type that is used as a placeholder. After
the template portion, the function swap () is declared, using T as the data type of the values that will be
swapped. In main () , the swap () function is called using three different types of data: ints, floats, and
chars. Because swap () is a generic function, the compiler automatically creates three versions of swap
(): one that will exchange integer values, one that will exchange floating-point values, and one that will
swap characters.
types.
Program 8.2
Solution:
#include <iostream.h>
template <class T1, class T2>
void myfunc (T1 x, T2 y)
{
cout << x << \t << y << \n;
}
void main()
{
myfunc (10, "I like C++");
myfunc (98.6, 19);
}
Output:
10
98.6
100
I like C++
19
Solution:
#include <iostream.h>
// First version of f() template.
template <class X> void f(X a)
{
cout << "Inside f(X a)\n";
}
// Second version of f() template.
template <class X, class Y> void f(X a, Y b)
{
cout << "Inside f(X a, Y b)\n";
}
int main()
{
f(10); // calls f(X)
f(10, 20); // calls f(X, Y)
return 0;
}
Here, the template for f() is overloaded to accept either one or two parameters
Program 8.3
Solution:
#include <iostream.h>
template <class T> void sort(X *a, int n)
{
101
int i,j;
T t;
for(i=1; i<n;i++)
for(j=n-1; j>=i; j--)
if(a[j-1] > a[j])
{
t = a[j-1];
a[j-1] = a[j];
a[j] = t;
}
}
void main()
{
int iarray[7] = {7, 5, 4, 3, 9, 8, 6};
double farray[5] = {2.6, -3.0, 1.2,9.6,8.9};
int i;
sort(iarray, 7);
sort(farray, 5);
cout << "Sorted INTEGER array is: ";
for(i=0; i<7; i++)
cout << iarray[i] << \t;
cout << "\nSorted CHARACTER array is: ";
for(i=0; i<5; i++)
cout << farray[i] << \t;
}
Output:
Sorted INTEGER array is: 3
4
Sorted CHARACTER array is:-3.0
5
1.2
6
2.6
7
8.9
8
9.6
102
class class-name
{
--------------------------------------};
General form of a member function definition of template class:
template <class T>
Ret_type class_name <T>:: function()
{
--------------------------------------}
General form of object creation of a template class:
class_name <data_type> object1, object2,.
Write a program to add two numbers (either two integers or floats) using
class templates.
Program 8.4
Solution:
#include <iostream.h>
template <class T>
class Add
{
T a, b;
public:
void getdata();
void display();
};
template <class T>
void Add <T>::getdata( )
{
cout<<Eneter 2 nos;
cin>>a>>b;
}
template <class T>
void Add <T>::display( )
{
103
cout<<sum=<<a+b;
}
void main()
{
Add <int> ob1;
Add <float> ob2;
ob1.getdata( );
ob1.display( );
ob2.getdata( );
ob2.display( );
}
Output:
Eneter 2 nos
Sum=9
Eneter 2 nos
Sum=9.9
4.8
5.1
Solution:
#include <iostream.h>
template <class Type1, class Type2>
class myclass
{
Type1 i;
Type2 j;
public:
myclass(Type1 a, Type2 b)
{
i = a; j = b;
}
void show()
{
cout << i << ' ' << j << '\n';
}
};
104 C++ by Er Sourav Kumar Giri, E-mail:[email protected]
void main()
{
myclass<int, double> ob1(10, 0.23);
myclass<char, char *> ob2('X', "Templates add power.");
ob1.show(); // show int, double
ob2.show(); // show char, char *
}
105
Assignment 8
Short Type Questions
1. Define template.
2. What are generic function and generic class?
3. Write the syntax to define a generic function.
4. Write the syntax to define a generic class.
106
Chapter 9
Standard Template Library
The Standard Template Library (STL) is a C++ software library that influenced many parts of
the C++ Standard Library It provides four components called algorithms, containers, functional and
iterators.
The STL provides a ready-made set of common classes for C++, such
as containers and associative arrays, that can be used with any built-in type and with any user-defined
type that supports some elementary operations (such as copying and assignment). STL algorithms are
independent of containers, which significantly reduces the complexity of the library.
The STL achieves its results through the use of templates. This approach provides compile-time
polymorphism that is often more efficient than traditional run-time polymorphism.
Modern C++ compilers are tuned to minimize any abstraction penalty arising from heavy use of the
STL.
At the core of the standard template library are three foundational items: containers, algorithms, and
iterators. These items work in conjunction with one another to provide off-the-shelf solutions to a
variety of programming problems.
Containers
Containers are objects that hold other objects, and there are several different types. For example, the
vector class defines a dynamic array, deque creates a double-ended queue, and list provides a linear
list. These containers are called sequence containers because in STL terminology, a sequence is a linear
list. In addition to the basic containers, the STL also defines associative containers, which allow efficient
retrieval of values based on keys. For example, a map provides access to values with unique keys. Thus,
a map stores a key/value pair and allows a value to be retrieved given its key. Each container class
defines a set of functions that may be applied to the container. For example, a list container includes
functions that insert, delete, and merge elements. A stack includes functions that push and pop values.
Algorithms
Algorithms act on containers. They provide the means by which you will manipulate the contents of
containers. Their capabilities include initialization, sorting, searching, and transforming the contents of
containers. Many algorithms operate on a range of elements within a container.
Iterators
Iterators are objects that are, more or less, pointers. They give you the ability to cycle through the
contents of a container in much the same way that you would use a pointer to cycle through an array.
There are five types of iterators:
Iterator
Random
Bidirectional
Forward
107
Access Allowed
Access Store and retrieve values. Elements may be accessed randomly.
Store and retrieve values. Forward and backward moving.
Store and retrieve values. Forward moving only.
Input
Output
In general, an iterator that has greater access capabilities can be used in place of one that has lesser
capabilities. For example, a forward iterator can be used in place of an input iterator. Iterators are
handled just like pointers. You can increment and decrement them.
You can apply the * operator to them. Iterators are declared using the iterator type defined by the
various containers.The STL also supports reverse iterators. Reverse iterators are either bidirectional or
random-access iterators that move through a sequence in the reverse direction. Thus, if a reverse
iterator points to the end of a sequence, incrementing that iterator will cause it to point to one element
before the end.
Vectors
Perhaps the most general-purpose of the containers is vector. The vector class supports a dynamic
array. This is an array that can grow as needed. As you know, in C++ the size of an array is fixed at
compile time. While this is by far the most efficient way to implement arrays, it is also the most
restrictive because the size of the array cannot be adjusted at run time to accommodate changing
program conditions. A vector solves this problem by allocating memory as needed. Although a vector is
dynamic, you can still use the standard array subscript notation to access its elements.
The template specification for vector is shown here:
template <class T, class Allocator = allocator<T>> class vector
Here, T is the type of data being stored and Allocator specifies the allocator, which defaults to the
standard allocator. vector has the following constructors:
explicit vector(const Allocator &a = Allocator( ) );
explicit vector(size_type num, const T &val = T ( ),
const Allocator &a = Allocator( ));
vector(const vector<T, Allocator> &ob);
template <class InIter> vector(InIter start, InIter end,
const Allocator &a = Allocator( ));
108
The first form constructs an empty vector. The second form constructs a vector that has num elements
with the value val. The value of val may be allowed to default. The third form constructs a vector that
contains the same elements as ob. The fourth form constructs a vector that contains the elements in
the range specified by the iterators start and end.
Any object that will be stored in a vector must define a default constructor. It must also define the <
and == operations. Some compilers may require that other comparison operators be defined. (Since
implementations vary, consult your compiler's documentation for precise information.) All of the builtin types automatically satisfy these requirements.
Although the template syntax looks rather complex, there is nothing difficult about declaring a vector.
Here are some examples:
vector<int> iv; // create zero-length int vector
vector<char> cv(5); // create 5-element char vector
vector<char> cv(5, 'x'); // initialize a 5-element char vector
vector<int> iv2(iv); // create int vector from an int vector
The following comparison operators are defined for vector:
==, <, <=, !=, >, >=
The subscripting operator [ ] is also defined for vector. This allows you to access the elements of a
vector using standard array subscripting notation.
Program 9.1
Solution:
#include <iostream>
#include <vector>
#include <cctype>
using namespace std;
void main ()
{
vector<char> v(10); // create a vector of length 10
int i;
// display original size of v
cout << "Size = " << v.size() << endl;
// assign the elements of the vector some values
for(i=0; i<10; i++) v[i] = i + 'a';
// display contents of vector
cout << "Current Contents:\n";
for(i=0; i<v.size(); i++) cout << v[i] << " ";
cout << "\n\n";
cout << "Expanding vector\n";
/* put more values onto the end of the vector,
it will grow as needed */
for(i=0; i<10; i++) v.push_back(i + 10 + 'a');
109
Output:
Size = 10
Current Contents:
abcdefghij
Expanding vector
Size now = 20
Current contents:
abcdefghijklmnopqrst
Modified Contents:
ABCDEFGHIJKLMNOPQRST
110
Assignment 9
111
Chapter 10
Namespace
The namespace keyword allows you to partition the global namespace by creating a declarative region.
In essence, a namespace defines a scope. The general form of namespace is shown here:
namespace name
{
// declarations
}
Anything defined within a namespace statement is within the scope of that namespace.
There is one difference between a class definition and a namespace definition: The namespace is
concluded with a closing brace but no terminating semicolon.
Example:
namespace A
{
int m;
void display(int n)
{
cout<<n;
}
}
using namespace A;
using namespace A::m;
m=100; //OK
m=100; //OK
display(200); //OK
display(200); // NOT OK, display is not visible
In general, to access a member of a namespace from outside its namespace, precede the member's
name with the name of the namespace followed by the scope resolution operator.
Here is a program that demonstrates the use of CounterNameSpace.
// Demonstrate a namespace.
#include <iostream.h>
namespace CounterNameSpace
{
int upperbound;
int lowerbound;
class counter
{
int count;
public:
counter(int n)
{
if(n <= upperbound) count = n;
else count = upperbound;
}
112
void reset(int n)
{
if(n <= upperbound) count = n;
}
int run()
{
if(count > lowerbound) return count--;
else return lowerbound;
}
};
}
void main()
{
CounterNameSpace::upperbound = 100;
CounterNameSpace::lowerbound = 0;
CounterNameSpace::counter ob1(10);
int i;
do
{
i = ob1.run();
cout << i << " ";
} while(i > CounterNameSpace::lowerbound);
cout << endl;
CounterNameSpace::counter ob2(20);
do
{
i = ob2.run();
cout << i << " ";
} while(i > CounterNameSpace::lowerbound);
cout << endl;
ob2.reset(100);
CounterNameSpace::lowerbound = 90;
Do
{
i = ob2.run();
cout << i << " ";
} while(i > CounterNameSpace::lowerbound);
}
Notice that the declaration of a counter object and the references to upperbound and lowerbound are
qualified by CounterNameSpace. However, once an object of type counter has been declared, it is not
necessary to further qualify it or any of its members. Thus, ob1.run() can be called directly; the
namespace has already been resolved.
113
using
As you can imagine, if your program includes frequent references to the members of a namespace,
having to specify the namespace and the scope resolution operator each time you need to refer to one
quickly becomes a tedious chore. The using statement was invented to alleviate this problem. The
using statement has these two general forms:
using namespace name;
using name::member;
In the first form, name specifies the name of the namespace you want to access. All of the members
defined within the specified namespace are brought into view (i.e., they become part of the current
namespace) and may be used without qualification. In the second form, only a specific member of the
namespace is made visible. For example, assuming CounterNameSpace as shown above, the following
using statements and assignments are valid.
using CounterNameSpace::lowerbound; // only lowerbound is visible
lowerbound = 10; // OK because lowerbound is visible
using namespace CounterNameSpace; // all members are visible
upperbound = 100; // OK because all members are now visible
Unnamed Namespaces
There is a special type of namespace, called an unnamed namespace that allows you to create
identifiers that are unique within a file. Unnamed namespaces are also called anonymous namespaces.
They have this general form:
namespace
{
// declarations
}
Unnamed namespaces allow you to establish unique identifiers that are known only within the scope of
a single file. That is, within the file that contains the unnamed namespace, the members of that
namespace may be used directly, without qualification. But outside the file, the identifiers are
unknown. Unnamed namespaces eliminate the need for certain uses of the static storage class
modifier.
For example, consider the following two files that are part of the same program.
File One
static int k;
void f1() {
k = 99; // OK
}
File Two
extern int k;
void f2() {
k = 10; // error
}
114
Because k is defined in File One, it may be used in File One. In File Two, k is specified as extern, which
means that its name and type are known but that k itself is not actually defined. When these two files
are linked, the attempt to use k within File Two results in an error because there is no definition for k. By
preceding k with static in File One, its scope is restricted to that file and it is not available to File Two.
While the use of static global declarations is still allowed in C++, a better way to accomplish the same
effect is to use an unnamed namespace. For example:
File One
namespace
{
int k;
}
void f1()
{
k = 99; // OK
}
File Two
extern int k;
void f2()
{
k = 10; // error
}
Here, k is also restricted to File One. The use of the unnamed namespace rather than static is
recommended for new code.
115
Output:
100
100
Here, NS is split into two pieces. However, the contents of each piece are still within the same
namespace, that is, NS.
116
tos--;
return stck[tos];
}
void main()
{
stack stck;
int i, j;
for(i=0; i<20; i++) stck.push(i);
j = stck; // convert to integer
cout << j << " items on stack.\n";
cout << SIZE - stck << " spaces open.\n";
}
Output:
20 items on stack.
80 spaces open.
As the program illustrates, when a stack object is used in an integer expression, such as j = stck, the
conversion function is applied to the object. In this specific case, the conversion function returns the
value 20. Also, when stck is subtracted from SIZE, the conversion function is also called.
118
Assignment 10
119
120
2
3
4
5
1
1
3
6
10
1
4
10
1
5
5. (a) Illustrate the use of virtual function in handling the ambiguity raised during
inheritance.
(b) Briefly explain the exception handling mechanism used in C++.
6. (a) Write a function template to find the binary equivalent of a decimal number.
(b) Mention the different roles of classes during design of a program.
Recursion.
Generic classes.
Namespaces.
*************
121
(b)
(c)
(d)
(e)
122
(f)
(g)
(h)
(i)
(j)
.
2.
};
____________ provides facilities for organizing the names in a programe to avoid name
clashes.
Differentiate between friend and inheritance.
____________ keywords supports dynamic method resolution.
What is the implicit pointer that is passed as the first argument for non-static member
functions?
____________ is the most general exception handler that catches exception of any type
Write a C++ program using class and object with constructor to convert the Fahrenheit to
Celsius and vice versa.
3.
4.
(a) Can we use compiler generated default assignment operator in case our class is using
dynamic memory ? Justify your answer?
(b) Write short notes on try, throw and catch block in C++.
5.
What is virtual function? When do we make a virtual function pure? What is the implication of
making a
pure virtual function? Explain with suitable examples.
6.
Write a program using pure virtual function to find out the area of circle, tringle and square.
7.
Write a program to read two double type numbers from keyboard and a function to calculate
the division of these two numbers. A try block to throw an exception when wrong type of data
is entered and another try Block to throw an exception if the condition division occurs.
Appropriate catch block to handle the exception thrown.
8.
(a) Differentiate between class template and template class with examples.
(b) Write short notes on STL.
*************
123
124
};
class Y:protected X
{
public:
int q;
};
int main()
{
Y yob;
yob.p=10;
yob .q=20;
cout<<yob.p<< <<yob.q<<endl;
return 0;
}
(f)What will be the output and why?
#include<iostream.h>
using namespace std;
class X
{
public:
void f1()
{cout<<x-Men<<endl;
]
virtual void f2()=0;
};
class Y:public X
{
public:
void f1()
{cout<<Y-Men<<endl;}
};
int main()
{
X *xp;
Y yob;
xp=&yob;
xp->f1();
return 0;
}
125
126
}
catch(double d)
{
cout<<caught an exception=<<d;
}
cout<<End<<endl;
return 0;
}
(j)What will be the output and why?
#include<iostream.h>
using namespace std;
template<class T1 void f(T1 tt1)
{ cout<<tt1=<<tt1<<endl;}
template<class T2> void f(T2 tt2)
{ cout<<tt2=<<tt2<<endl;}
int main()
{
f(1000);
f(101.7);
return 0;
}
2. (a)Create a class called student which contains protected attributes such as stud_name ,
stud_branch. Provide an appropriate method to take user input to initialize these attributes and
display the details regarding 50 students of a class.
(b)Create a class called Area which contains a method called find_area. Write down
appropriate code to create objects named as circle and rectangle of the above class and
implement function overloading to calculate area of a rectangle and area of a circle based
upon user input.
3. (a)Write a C++ program to convert a primitive or built in type value such as int or char to a user
defined type value such as class A or class X.
(b)Write a C++ program where you can only be able to create a single instance of a class. Upon
trying to create more than one number of instances will result in termination of a program.
4. (a)Create a class called point with two integer attributes such as x and y to represent its xcoordinate and y-coordinate. Provide constructor to initialize the attributes. Provide another
method named as move () which will move the coordinates only in the direction of x-axis for 10
unit at a time. Also display the new and old values of the coordinates.
127
(b)With an appropriate example, explain the role of virtual base class in removing ambiguities in
case of diamond inheritance which is a special case of multi path inheritance.
5. (a)Create an abstract class called Figure which contains a pure virtual function called
find_area() and a protected attribute named as area. Create two new derived classes from the
above class named as Circle and Square having double type attribute named as radius and side
respectively. Implement dynamic polymorphism to find out area of a circle and a square, and
show the result.
(b)Write appropriate code to overload the pre increment and post increment operators in a
same program using non member operator functions.
6. (a)Suppose there is a class called X with a double type attribute. Write a C++ program to create
three objects named as ob 1, ob 2 and ob 3 of the above class and perform the following
operations:
ob2=5.5 + ob1
ob3=ob1 + 6.7
(b)Write a complete program to create a class named Student with protected attributes such as
id and marks. The attributes should be initialized only through constructors. The class contains
a public method named as show() to display the initialized attributes. Provide a mechanism to
create an array of student objects. The array size should be given by the user at run-time.
7. (a)Provide at least one good reason to choose a const reference rather than a reference
variable as a parameter to a copy constructor. Explain with a suitable example.
(b)Write a complete program where you achieve the following conversion within main():
A ob1(10), ob2(101.5);
int i=ob1;
double d=ob2;
Where A is a user defined class .
8. (a)Write a complete program where you can restrict a user defined function to throw only int or
char type exception out of it.
(b)Write a complete program to declare and define a generic function that is capable of
arranging any kind of elements in descending order.
*************
128
(b)
(c)
(d)
(e)
129
};
int main()
{
X xob;
xob.show();
return 0;
}
State the differences between the following two declarations with examples:
Const int *p; and int *const p;
What will be the output and why?
#include<iostream.h>
using namespace std;
class A
{ int i;
public:
static void f() {i=20;i++;}
};
int main()
{ A ob 1 , ob2;
ob 1.f();
ob2.f();
return o;
}
Private attributes cant be inherited. State a remedy for this problem so that attributes of a
class behave like private attributes but can be inherited. Explain with an example.
What will be the output and why?
using namespace;
struct X
{int p;};
struct Y:protected X
{int q;};
Int main()
{
C++ by Er Sourav Kumar Giri, E-mail:[email protected]
Y yob;
yob.p=11;
yob.q=22;
cout<<yob.p<< <<yob.q<<endl;
return 0;
}
(f) What will be the output and why?
using namespace std;
class X
{
int p;
public:
friend void f(int a);
};
void f(int a)
{
P=a;
cout<<p=<<p<<endl;
}
int main()
{
f(200)
return 0;
}
(g) What will be the output and why?
using namespace std;
class X
{
int a
public:
X(int p){a=p;}
};
class Y
{
public:
int b;
};
public:
D(int k){b=k;}
void show(){cout<<b=<<b<<endl;}
};
int main()
{
D dob(100);
dob.show();
return 0;
130
2. (a) Create a class called Employee which contains protected attributes such as emp_id,
emp_salary and emp_da. emp_da is 20% of the emp_salary. Provide an appropriate method to
take user input to initialize the attributes and display the details regarding 25 students of a
class.
131
(b) Create a class called Volume which contains a method called find_vol. write down
appropriate code to create objects named as sphere and cylinder of the above class and
implement function overloading to calculate volume of a sphere and cylinder based upon user
input.
3. (a) Write a C++ program to convert a primitive or built in type value such as int or char to a user
defined type value such as class A or class X.
(b) Write a C++ program where you can only be able to create a single instance of a class. Upon
trying to create more than one number of instances will result in termination of the program.
4. (a) With an appropriate example, explain how ambiguities can be resolved for public and
protected attributes in case of multi path inheritance without using virtual base class.
(b) Create an abstract class called Shape which contains a pure function called find_vol() and a
protected attribute named as volume. Create two new derived classes from the above class
named as Cube and Sphere having double type attribute named as side and radius respectively.
Implement dynamic polymorphism to find out volume of a cube and a sphere. Also display the
result.
5. (a) Write appropriate code to overload the bit-wise << operator to perform the following task:
int y= x<<ob;
where ob is an object of class myclass with a single int attribute and x is an int declared in
main() and its value is to be supplied by the user.
(b) Suppose there is a class called X with two double type attributes. Write a c++ program to
create two objects named ob 1 and ob 2 of the above class and overload the binary == operator
to perform the following operation within main():
if(ob 1== ob 2)
cout<<Objects are same<<endl;
else
cout<<Objects are different<<endl;
6. (a) Suppose there is a class X with a double type attribute. Write a c++ program to create three
objects named as ob1, ob2 and ob3 of the above class and perform the following operation:
Ob2 = 5.5 + ob 1;
Ob 3 = ob1 + 6.7;
132
(b) Write an appropriate C++ code showing ambiguity resolving mechanism where a class
attribute has same name as that of a local parameter of a member by using this pointer.
7. (a) Write a complete program to create a class called Account with protected attributes such as
account number and balance. The attributes should be initialized through constructors. The
class contains a public method named as show () to display the initialized attributes. Provide a
mechanism to create an array of Account objects. The array size should be given by the user at
run time.
(b) What is a copy constructor? Explain the role of a copy constructor while initializing a
pointer attribute of a class for which the memory allocation takes place at the run time.
8. (a) Write a complete program where you can perform the following conversion within main() :
A ob 1 (5.5), ob2;
int i=10;
double d=ob 1;
ob2=i; where A is a user defined class.
(b) Write a complete program where an exception of type double can be rethrown.
**************
133