You are on page 1of 24

Roll No.

: -------------------------------

MCA SECOND SEMESTER


MODEL TEST PAPER-II
Object Oriented Programming in C++ MCA-104

Time: 3 Hrs

Total Marks: 60

Instructions:
1. Write your class roll no at the top, immediately on receipt of this Q/Paper.
2. Attempt five questions in all including Q1 which is compulsory. Attempt one
question from each unit.

Q1:

Short answer type:

(10*2=20)

a) What do you know about runtime polymorphism?


Ans: - At runtime, when it is known what class objects are under consideration, the
appropriate version of the function is invoked. Since the functions are linked with a
particular class much later after the compilation, this process is termed as late binding. It
is also known as dynamic binding because the selection of the appropriate function is
done automatically at runtime. If the appropriate member function could be selected
while the program is running. This is known as run time polymorphism. C++ supports a
mechanism known as virtual function to achieve runtime polymorphism.
b) Can inheritance be private? Comment.
Ans: - The normal way of expressing inheritance in C++ is
Class Derived: public Base {
// stuff
};
When this is done, Derived is a subtype of Base, and anywhere one encounters a Base *
or Base & one can substitute a Derived */Derived &.
To get private inheritance, one does:
Class Derived: private Base {// private keyword is actually optional
//stuff
};
The private inheritance is the default type of inheritance for classes but not for structsi.e. if
you omit the "public" keyword in the inheritance specification, you get private inheritance.
1

Consequences of private inheritance:


All public and protected members of Base become private members of Derived--i.e. the
class can use them, but external clients cannot. (However, the definition for Derived can
re-declare these to be public or protected; members which were originally protected can
only be re-declared as protected, not public).
Derived is not a subtype of Base, trying to static_cast a pointer from derived to base (or
cast one implicitly) will result in a compiler error.

If private inheritance broke the subtype link but didn't make all the members private, it
might be more useful but since it does make members private, it isn't very good.
c) How is exception handling is beneficial for object oriented programming?
Ans: - Advantages of Using Exception Handling
Exception handling provides the following advantages over ``traditional'' error
management techniques:
1. separating Error Handling Code from ``regular'' one
provides a way to separate the details of what to do when something out-of-the-ordinary
happens from the normal logical flow of the program code;
2. propagating Errors Up the Call Stack
lets the corrective action to be taken at a higher level. This allows the corrective action to
be taken in the method that calling that one where an error occurs;
3. grouping Error Types and Error Differentiation
allows to create similar hierarchical structure for exception handling so groups they in
logical way.
d) Explain the concept of namespaces in C++?
Ans: - A namespace is designed to overcome this difficulty and is used as additional
information to differentiate similar functions, classes, variables etc. with the same name
available in different libraries. Using namespace, you can define the context in which
names are defined. In essence, a namespace defines a scope.
Defining a Namespace:
A namespace definition begins with the keyword namespace followed by the namespace
name as follows:
namespace namespace_name {
// code declarations
}
To call the namespace-enabled version of either function or variable, prepend the
namespace name as follows:
2

name::code; // code could be variable or function.


e) What are run time memory constructs in C++?
Ans:- A good understanding of how dynamic memory really works in C++ is essential to
becoming a good C++ programmer. Memory in your C++ program is divided into two
parts:

The stack: All variables declared inside the function will take up memory from the stack.
The heap: This is unused memory of the program and can be used to allocate the
memory dynamically when program runs.

Many times, you are not aware in advance how much memory you will need to store
particular information in a defined variable and the size of required memory can be
determined at run time.
You can allocate memory at run time within the heap for the variable of a given type using a
special operator in C++ which returns the address of the space allocated. This operator is
called new operator.
The new and delete operators:
There is following generic syntax to use new operator to allocate memory dynamically for
any data-type.
new data-type;

Here, data-type could be any built-in data type including an array or any user defined data types
include class or structure. Let us start with built-in data types. For example we can define a
pointer to type double and then request that the memory be allocated at execution time. We can
do this using the new operator with the following statements:
double* pvalue

= NULL; // Pointer initialized with null

f) Discuss the operators that cannot be overloaded?


Ans: - In C++, following operators cannot be overloaded:
. (Member Access or Dot operator)
?: (Ternary or Conditional Operator )
:: (Scope Resolution Operator)
.* (Pointer-to-member Operator )
sizeof (Object size Operator)
typeid (Object type Operator)
g) What are reference variables?
3

Ans: - C++ references allow you to create a second name for the variable that you can
use to read or modify the original data stored in that variable. While this may not sound
appealing at first, what this means is that when you declare a reference and assign it a
variable, it will allow you to treat the reference exactly as though it were the original
variable for the purpose of accessing and modifying the value of the original variable-even if the second name (the reference) is located within a different scope. This means,
for instance, that if you make your function arguments references, and you will
effectively have a way to change the original data passed into the function. This is quite
different from how C++ normally works, where you have arguments to a function copied
into new variables.
Syntax: - Declaring a variable as a reference rather than a normal variable simply entails
appending an ampersand to the type name, such as this "reference to an int"
int& foo = ....;

h) What are pure abstract classes in C++? Explain with syntax.


Ans: - Pure Abstract Classes
An abstract class is one in which there is a declaration but no definition for a member
function. The way this concept is expressed in C++ is to have the member function
declaration assigned to zero.
Example
class PureAbstractClass
{
public:
virtual void AbstractMemberFunction() = 0;
};

A pure Abstract class has only abstract member functions and no data or concrete
member functions. In general, a pure abstract class is used to define an interface and is
intended to be inherited by concrete classes. It's a way of forcing a contract between the
class designer and the users of that class. The users of this class must declare a matching
member function for the class to compile.
i) Can a class have constant objects? Comment.
Ans: - Const class objects and member functions :
Just like the built-in data types (int, double, char, etc), class objects can be made const
by using the const keyword. All const variables must be initialized at time of creation. In
the case of built-in data types, initilization is done through explicit or implicit
assignment:
1

const int nValue = 5; // initialize explicitly

const int nValue2(7); // initialize implictly

In the case of classes, this initialization is done via constructors:


Date cDate; // initialize using default constructor
1 const
const Date cDate2(10, 16, 2020); // initialize using parameterized
2constructor

If a class is not initialized using a parameterized constructor, a public default constructor must be
provided if no public default constructor is provided in this case, a compiler error will occur.
Once a const class object has been initialized via constructor, any attempt to modify the member
variables of the object is disallowed, as it would violate the constness of the object. This
includes both changing member variables directly (if they are public), or calling member
functions that sets the value of member variables:
j) What is the use of this pointer in a class?
Ans: - 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
member functions have a this pointer.
Unit -I
Q2:- What is Operator overloading? Explain different types? Write a program of
overloading binary operator?
(10)
Ans: - One of the nice features of C++ is that you can give special meanings to operators, when
they are used with user-defined classes. This is called operator overloading. You can implement
C++ operator overloads by providing special member-functions on your classes that follow a
particular naming convention. For example, to overload the + operator for your class, you would
provide a member-function named operator+ on your class.
The following set of operators is commonly overloaded for user-defined classes:

= (assignment operator)
+ - * (binary arithmetic operators)

+= -= *= (compound assignment operators)

== != (comparison operators)

Overloadable/Non-overloadableOperators:
5

Following is the list of operators which can be overloaded:


+
&
<
<<
+=
|=
->

|
>
>>
-=
*=
->*

*
~
<=
==
/=
<<=
new

/
!
>=
!=
%=
>>=
new []

%
,
++
&&
^=
[]
delete

^
=
-||
&=
()
delete []

ALGORITHM:
Step 1: Start the program.
Step 2: Declare the class.
Step 3: Declare the variables and its member function.
Step 4: Using the function getvalue() to get the two numbers.
Step 5: Define the function operator +() to add two complex numbers.
Step 6: Define the function operator ()to subtract two complex numbers.
Step 7: Define the display function.
Step 8: Declare the class objects obj1,obj2 and result.
Step 9: Call the function getvalue using obj1 and obj2
Step 10: Calculate the value for the object result by calling the function operator + and
operator -.
Step 11: Call the display function using obj1 and obj2 and result.
Step 12: Return the values.
Step 13: Stop the program.
PROGRAM:
#include<iostream.h>
#include<conio.h>
class complex
{
public:

int a,b;
void getvalue()
{
cout<<"Enter the value of Complex Numbers a,b:";
cin>>a>>b;
}
complex operator+(complex ob)
{
complex t;
t.a=a+ob.a;
t.b=b+ob.b;
return(t);
}
complex operator-(complex ob)

complex t;
t.a=a-ob.a;
t.b=b-ob.b;
return(t);

}
void display()
{
}

cout<<a<<"+"<<b<<"i"<<"\n";

};
void main()
{
clrscr();
complex obj1,obj2,result,result1;
obj1.getvalue();
obj2.getvalue();
result = obj1+obj2;
result1=obj1-obj2;
cout<<"Input Values:\n";
obj1.display();
obj2.display();
cout<<"Result:";
result.display();
result1.display();
getch();
}
Output:
Enter the value of Complex Numbers a, b
4
5
Enter the value of Complex Numbers a, b
2
2
Input Values
4 + 5i
2 + 2i
Result
6 +
7i
2 +
3i

Different types of operator overloading are:Unary and binary operator overloading


There are two types of operator overloading:

Unary operator overloading


7

Binary operator overloading

Example of Unary Operator overloading:The unary operators operate on a single operand and following are the examples of Unary
operators:

The increment (++) and decrement (--) operators.


The unary minus (-) operator.

The logical not (!) operator.

The unary operators operate on the object for which they were called and normally, this operator
appears on the left side of the object, as in !obj, -obj, and ++obj but sometime they can be used
as postfix as well like obj++ or obj--.
Following example explain how minus (-) operator can be overloaded for prefix as well as
postfix usage.
#include <iostream>
using namespace std;
class Distance
{
private:
int feet;
// 0 to infinite
int inches;
// 0 to 12
public:
// required constructors
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
// method to display distance
void displayDistance()
{
cout << "F: " << feet << " I:" << inches <<endl;
}
// overloaded minus (-) operator
Distance operator- ()
{
feet = -feet;
inches = -inches;
return Distance(feet, inches);
}
};
int main()
{

Distance D1(11, 10), D2(-5, 11);

-D1;
D1.displayDistance();

// apply negation
// display D1

-D2;
D2.displayDistance();

// apply negation
// display D2

return 0;

When the above code is compiled and executed, it produces the following result:
F: -11 I:-10
F: 5 I:-11

Q3:- Explain the concept of Namespaces in C++ with example?

(10)

Ans: - Namespaces
Namespaces allow to group entities like classes, objects and functions under a name. This way
the global scope can be divided in "sub-scopes", each one with its own name.
The format of namespaces is:
namespace identifier
{
entities
}
Where identifier is any valid identifier and entities is the set of classes, objects and functions that
are included within the namespace. For example:
namespace myNamespace
{
int a, b;
}
In this case, the variables a and b are normal variables declared within a namespace called
myNamespace. In order to access these variables from outside the myNamespace namespace we
have to use the scope operator :: For example, to access the previous variables from outside
myNamespace we can write:
myNamespace::a
myNamespace::b
9

The functionality of namespaces is especially useful in the case that there is a possibility that a
global object or function uses the same identifier as another one, causing redefinition errors. For
example:
// namespaces
#include <iostream>
using namespace std;
namespace first
{
int var = 5;
}
namespace second
{
double var = 3.1416;
}
int main () {
cout << first::var << endl;
cout << second::var << endl;
return 0;
}
In this case, there are two global variables with the same name: var. One is defined within the
namespace first and the other one in second. No redefinition errors happen thanks to namespaces.
using
The keyword using is used to introduce a name from a namespace into the current declarative
region. For example:
// using
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
10

int main () {
using first::x;
using second::y;
cout << x << endl;
cout << y << endl;
cout << first::y << endl;
cout << second::x << endl;
return 0;
}
The keyword using can also be used as a directive to introduce an entire namespace:
// using
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
int main () {
using namespace first;
cout << x << endl;
cout << y << endl;
cout << second::x << endl;
cout << second::y << endl;
return 0;
}
In this case, since we have declared that we were using namespace first, all direct uses of x and y
without name qualifiers was referring to their declarations in namespace first.
Using namespace have validity only in the same block in which they are stated or in the entire
code if they are used directly in the global scope. For example, if we had the intention to first use
the objects of one namespace and then those of another one, we could do something like:
// using namespace example 5
11

#include <iostream>
using namespace std;
namespace first
{
int x = 5;
}
namespace second
{
double x = 3.1416;
}

3.1416

int main () {
{
using namespace first;
cout << x << endl;
}
{
using namespace second;
cout << x << endl;
}
return 0;
}
Namespace alias
We can declare alternate names for existing namespaces according to the following format:
namespace new_name = current_name;
Namespace std
All the files in the C++ standard library declare all of its entities within the std namespace. That
is why we have generally included the using namespace std; statement in all programs that used
any entity defined in iostream.
Unit -II
Q4:- Explain the concept of Inheritance and Friendship in C++ with examples? (10)

12

Ans: - Friendship and inheritance: - In principle, private and protected members of a class
cannot be accessed from outside the same class in which they are declared. However, this
rule does not apply to "friends".
Friends are functions or classes declared with the friend keyword.
A non-member function can access the private and protected members of a class if it is
declared a friend of that class. That is done by including a declaration of this external
function within the class, and preceding it with the keyword friend:
Friend functions
In principle, private and protected members of a class cannot be accessed from outside the same
class in which they are declared. However, this rule does not affect friends.
Friends are functions or classes declared as such.
If we want to declare an external function as friend of a class, thus allowing this function to have
access to the private and protected members of this class, we do it by declaring a prototype of
this external function within the class, and preceding it with the keyword friend:
// friend functions
#include <iostream>
using namespace std;
class CRectangle {
int width, height;
public:
void set_values (int, int);
int area () {return (width * height);}
friend CRectangle duplicate (CRectangle);
};
void CRectangle::set_values (int a, int b) {
width = a;
height = b;

}
CRectangle duplicate (CRectangle rectparam)
{
CRectangle rectres;
rectres.width = rectparam.width*2;
rectres.height = rectparam.height*2;
return (rectres);
}
int main () {
CRectangle rect, rectb;
rect.set_values (2,3);

13

rectb = duplicate (rect);


cout << rectb.area();
return 0;
}

The duplicate function is a friend of CRectangle. From within that function we have been able to
access the members width and height CRectangle, which are private members. Notice that
neither in the declaration of duplicate() nor in its later use in main() have we considered
duplicate a member of class CRectangle. Simply has access to its private and protected members
without being a member of different objects of type
The friend functions can serve, for example, to conduct operations between two different classes.
Generally, the use of friend functions is out of an object-oriented programming methodology, so
whenever possible it is better to use members of the same class to perform operations with them.
Friend classes
Just as we have the possibility to define a friend function, we can also define a class as friend of
another one, granting that first class access to the protected and private members of the second
one.
// friend class
#include <iostream>
using namespace std;
class CSquare;
class CRectangle {
int width, height;
public:
int area ()
{return (width * height);}
void convert (CSquare a);
};
class CSquare {
private:
int side;
public:
void set_side (int a)
{side=a;}
friend class CRectangle;
};
void CRectangle::convert (CSquare a) {
width = a.side;
height = a.side;
}
int main () {
CSquare sqr;
CRectangle rect;
sqr.set_side(4);

14

rect.convert(sqr);
cout << rect.area();
return 0;
}

In this example, we have declared CRectangle as a friend of CSquare so that CRectangle


member functions could have access to the protected and private members of CSquare, more
concretely to CSquare::side, which describes the side width of the square.
Consider that friendships are not corresponded if we do not explicitly specify so. In our example,
CRectangle is considered as a friend class by CSquare, but CRectangle does not consider
CSquare to be a friend, so CRectangle can access the protected and private members of CSquare
but not the reverse way. Of course, we could have declared also CSquare as friend of CRectangle
if we wanted to.
Another property of friendships is that they are not transitive: The friend of a friend is not
considered to be a friend unless explicitly specified
Q5:- What is the mechanism of Late binding? Explain the process and also explain the
rules for the same.
(10)
Ans: - Mechanism of Late Binding:-

15

At runtime, when it is known what class objects are under consideration, the appropriate version
of the function is invoked. Since the functions are linked with a particular class much later after
the compilation, this process is termed as late binding. It is also known as dynamic binding
because the selection of the appropriate function is done automatically at runtime.
If the appropriate member function could be selected while the program is running. This is
known as run time polymorphism. C++ supports a mechanism known as virtual function to
achieve runtime polymorphism.

Unit -III
Q6:- What are pure virtual functions in C++? Explain with the help of a program. Also
explain the rules of virtual functions?
(10)
Ans:- Pure Virtual Function - C++
A virtual function body is known as Pure Virtual Function. In above example we can see that the
function is base class never gets invoked. In such type of situations we can use pure virtual
functions
Example : same example can re-written
class base
{
16

public:
virtual void show()=0; //pure virtual function
};
class derived1 : public base
{
public:
void show()
{
cout<<"\n Derived 1";
}
};
class derived2 : public base
{
public:
void show()
{
cout<<"\n Derived 2";
}
};
void main()
{
base *b; derived1 d1; derived2 d2;
b = &d1;
b->show();
b = &d2;
b->show();
}
Rules for Virtual Functions
1. The virtual function must be member of class
2. They cannot be static members
3. They are accessed by using object pointers
4. Prototype of base class function & derived class must be same
5. Virtual function in base class must be defined even though it is not used
6. A virtual function can be friend function of another class
7. We could not have virtual constructor
8. If a virtual function is derived in base class, it need not be necessarily redefined in the derived
class
9. Pointer object of base class can point to any object of derived class but reverse is not true
10. When a base pointer points to derived class, incrementing & decrementing it will not make it
point to the next object of derived class
17

Q7:- Describe different methods of opening a file. Write an interactive program that
accepts records and stores them in a file.
(10)
Ans: - Different file opening modes in C++ are as follows:
Modes
ios::in
ios::out
ios::binary
ios::truncate
ios::app
ios::ate
ios::nocreate
ios::noreplace

Description
Opens a file for reading. New contents cannot be written in the file.
Opens a file for writing. If file exist already then its contents are deleted
but if the file does not exist it will create a new file.
It opens a file in binary form.
Opens a file for writing. If file already exists then its previous contents
are replaced with the new contents.
Opens a file in append mode. It adds new content at the end of the file.
It is used to write new contents at the end of the file and we can also
modify the previous contents.
It does not allow to create a new file if it does not exist.
It does replace the old file with new file.

A header file fstream.h is used in order to work with the files in C++ which include functions for
opening and closing files.
For opening a file:
In order to open a file open() member function of fstreams class is used.
Syntax: open (filename, mode)
Here filename is the name of the file to open and mode can be mode available in C++.
For closing a file:
In order to close a file close() member function of fstreams class is used. This function takes no
arguments.
Different classes used for reading and writing to and from files are as follows:
Classes
ofstream
ifstream
fstream

Description
This class is used for writing onto files
It is used for reading from files
It is used for both reading and writing onto files

Program: - This Menu Driven Program explains how to take get data from user, how to
append data, how to modify record and how to display records.
#include <iostream.h>
#include <fstream.h>

18

#include <conio.h>
staticint totrec=0;
//totrec variable keep track for total variable
entered//Initially Record scanned are Zerovoid main()
{
int choice;
while(1)
{
clrscr();
cout<<"Choose your choice\nNOTE : one choice for one record(except viewing
data)\n";
cout<<"1) Scanning intial records\n";
cout<<"2) Appending records\n";
cout<<"3) Modifying or append records\n";
cout<<"4) Viewing records\n";
cout<<"5) Exit\n";
cout<<"Enter your choice : ";
cin>>choice;
switch (choice)
{
case 1 :
{
ofstream outfile;
outfile.open("emp",ios::out);
cout<<"\n\nPlease enter the details as per demanded\n";
cout<<"\nEnter the name : ";
char name[20];
cin>>name;
outfile<<name<<endl;
cout<<"Enter Age : ";
int age;
cin>>age;
outfile<<age<<endl;
cout<<"Enter programming language known by him\her : ";
char lang[25];
cin>>lang;
outfile<<lang<<endl;
totrec= totrec + 1;
outfile.close();
}
break;
case 2 :
{
ofstream outfile;
outfile.open("emp",ios::app);
cout<<"\n\nPlease enter the details as per demanded\n";
cout<<"\nEnter the name : ";
char name[20];
cin>>name;
outfile<<name<<endl;
cout<<"Enter Age : ";
int age;
cin>>age;
outfile<<age<<endl;
cout<<"Enter programming language known by him : ";
char lang[25];
cin>>lang;
outfile<<lang<<endl;

19

totrec = totrec + 1;
outfile.close();
}
break;
case 3 :
{
ofstream outfile;
outfile.open("emp",ios::ate);
cout<<"Are you interested in adding record\nenter y or n\n";
char ans;
cin>>ans;
if(ans=='y' || ans=='Y')
{
cout<<"\n\nPlease enter the details as per demanded\n";
cout<<"\nEnter the name : ";
char name[20];
cin>>name;
outfile<<name<<endl;
cout<<"Enter Age : ";
int age;
cin>>age;
outfile<<age<<endl;
cout<<"Enter programming language known by him : ";
char lang[25];
cin>>lang;
outfile<<lang<<endl;
totrec = totrec + 1;
}
outfile.close();
}
break;
case 4 :
{
ifstream infile;
infile.open("emp",ios::in);
constint size=80;
char line[size];
int counter=totrec;
while(counter > 0)
{
infile.getline(line,size);
cout<<"\n\nNAME
: "<<line<<endl;
infile.getline(line,size);
cout<<"AGE
: "<<line<<endl;
infile.getline(line,size);
cout<<"LANGUAGE : "<<line<<endl;
counter--;
}
infile.close();
}
getch();
break;
case 5 : gotoout;
default : cout<<"\nInvalid Choice\nTRY AGAIN\n";
}

}
out:
}

20

Unit IV
Q8:- What are the basic components of STL in C++? Explain with an example? (10)
Ans: - The Standard Template Library is a collection of classes that provide templated
containers, algorithms, and iterators. If you need a common class or algorithm, odds are the STL
has it. The upside is that you can take advantage of these classes without having to write and
debug the classes yourself, and the STL does a good job providing reasonably efficient versions
of these classes. The downside is that the STL is complex, and can be a little intimidating since
everything is templated.
At the core of the C++ Standard Template Library are following three well-structured
components:
Component
Containers
Algorithms
Iterators

Description
Containers are used to manage collections of objects of a certain
kind. There are several different types of containers like deque, list,
vector, map etc.
Algorithms act on containers. They provide the means by which
you will perform initialization, sorting, searching, and transforming
of the contents of containers.
Iterators are used to step through the elements of collections of
objects. These collections may be containers or subsets of
containers.

We will discuss about all the three C++ STL components in next chapter while discussing C++
Standard Library. For now, keep in mind that all the three components have a rich set of predefined functions which help us in doing complicated tasks in very easy fashion.
Let us take the following program demonstrates the vector container (a C++ Standard Template)
which is similar to an array with an exception that it automatically handles its own storage
requirements in case it grows:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// create a vector to store int
vector<int> vec;
int i;
// display the original size of vec
cout << "vector size = " << vec.size() << endl;
// push 5 values into the vector

21

for(i = 0; i < 5; i++){


vec.push_back(i);
}
// display extended size of vec
cout << "extended vector size = " << vec.size() << endl;
// access 5 values from the vector
for(i = 0; i < 5; i++){
cout << "value of vec [" << i << "] = " << vec[i] << endl;
}
// use iterator to access the values
vector<int>::iterator v = vec.begin();
while( v != vec.end()) {
cout << "value of v = " << *v << endl;
v++;
}
return 0;
}

When the above code is compiled and executed, it produces the following result:
vector size = 0
extended vector size = 5
value of vec [0] = 0
value of vec [1] = 1
value of vec [2] = 2
value of vec [3] = 3
value of vec [4] = 4
value of v = 0
value of v = 1
value of v = 2
value of v = 3
value of v = 4

Here are following points to be noted related to various functions we used in the above example:

The push_back( ) member function inserts value at the end of the vector, expanding its
size as needed.
The size( ) function displays the size of the vector.

The function begin( ) returns an iterator to the start of the vector.

The function end( ) returns an iterator to the end of the vector.

Q9:- What is Template specialization? Write a program to implement template


specialization.
(10)

22

Ans: - Template specialization


It is possible to define a different implementation for a template when a specific type is passed as
template
argument.
This
is
called
a
template
specialization.
For example, let's suppose that we have a very simple class called mycontainer that can store one
element of any type and that has just one member function called increase, which increases its
value. But we find that when it stores an element of type char it would be more convenient to
have a completely different implementation with a function member uppercase, so we decide to
declare a class template specialization for that type:
// template specialization
#include <iostream>
using namespace std;
// class template:
template <class T>
class mycontainer {
T element;
public:
mycontainer (T arg) {element=arg;}
T increase () {return ++element;}
};
// class template specialization:
template <>
class mycontainer <char> {
char element;
public:
mycontainer (char arg) {element=arg;}
char uppercase ()
{
if ((element>='a')&&(element<='z'))
element+='A'-'a';
return element;
}
};
int main () {
mycontainer<int> myint (7);
mycontainer<char> mychar ('j');
cout << myint.increase() << endl;
cout << mychar.uppercase() << endl;
return 0;
}

This is the syntax used for the class template specialization:


template <> class mycontainer <char> { ... };

First of all, notice that we precede the class name with template<> , including an empty
parameter list. This is because all types are known and no template arguments are required for
23

this specialization, but still, it is the specialization of a class template, and thus it requires to be
noted
as
such.
But more important than this prefix, is the <char> specialization parameter after the class
template name. This specialization parameter itself identifies the type for which the template
class is being specialized (char). Notice the differences between the generic class template and
the specialization:
1 template <class T> class mycontainer { ... };
2 template <> class mycontainer <char> { ... };

The first line is the generic template, and the second one is the specialization.
When we declare specializations for a template class, we must also define all its members, even
those identical to the generic template class, because there is no "inheritance" of members from
the
generic
template
to
the
specialization.

24

You might also like