You are on page 1of 132

Explain the file handling mechanism of c++?Explain the different modes of file handling?

Give an eg to read and write data to and from a file?


File. The information / data stored under a specific name on a storage device, is called a file.
Stream. It refers to a sequence of bytes.
Text file. It is a file that stores information in ASCII characters. In text files, each line of text is
terminated with a special character known as EOL (End of Line) character or delimiter character.
When this EOL character is read or written, certain internal translations take place.
Binary file. It is a file that contains information in the same format as it is held in memory. In
binary files, no delimiters are used for a line and no translations occur here.
Classes for file stream operation
ofstream: Stream class to write on files
ifstream: Stream class to read from files
fstream: Stream class to both read and write from/to files.
Opening a file
OPENING FILE USING CONSTRUCTOR
ofstream outFile("sample.txt"); //output only
ifstream inFile(sample.txt); //input only
OPENING FILE USING open()
Stream-object.open(filename, mode)
ofstream outFile;
outFile.open("sample.txt");
ifstream inFile;
inFile.open("sample.txt");
File mode parameter

Meaning

ios::app

Append to end of file

ios::ate

go to end of file on opening

ios::binary

file open in binary mode

ios::in

open file for reading only

ios::out

open file for writing only

ios::nocreate

open fails if the file does not exist

ios::noreplace

open fails if the file already exist

ios::trunc

delete the contents of the file if it exist

All these flags can be combined using the bitwise operator OR (|). For example, if we want to
open the file example.bin in binary mode to add data we could do it by the following call to
member function open():
fstream file;
file.open ("example.bin", ios::out | ios::app | ios::binary);
Closing File
outFile.close();
inFile.close();
INPUT AND OUTPUT OPERATION
put() and get() function
the function put() writes a single character to the associated stream. Similarly, the function get()
reads a single character form the associated stream.
example :
file.get(ch);
file.put(ch);
write() and read() function
write() and read() functions write and read blocks of binary data.
example:
file.read((char *)&obj, sizeof(obj));
file.write((char *)&obj, sizeof(obj));
ERROR HANDLING FUNCTION
FUNCTION

RETURN VALUE AND MEANING

eof()

returns true (non zero) if end of file is encountered while


reading; otherwise return false(zero)

fail()

return true when an input or output operation has failed

bad()

returns true if an invalid operation is attempted or any


unrecoverable error has occurred.

good()

returns true if no error has occurred.

File Pointers And Their Manipulation


All i/o streams objects have, at least, one internal stream pointer:
ifstream, like istream, has a pointer known as the get pointer that points to the element to be read
in the next input operation.

ofstream, like ostream, has a pointer known as the put pointer that points to the location where
the next element has to be written.
Finally, fstream, inherits both, the get and the put pointers, from iostream (which is itself derived
from both istream and ostream).
These internal stream pointers that point to the reading or writing locations within a stream can
be manipulated using the following member functions:
seekg()

moves get pointer(input) to a specified location

seekp()

moves put pointer (output) to a specified location

tellg()

gives the current position of the get pointer

tellp()

gives the current position of the put pointer

The other prototype for these functions is:


seekg(offset, refposition );
seekp(offset, refposition );
The parameter offset represents the number of bytes the file pointer is to be moved from the
location specified by the parameter refposition. The refposition takes one of the following three
constants defined in the ios class.
ios::beg
start of the file
ios::cur
current position of the pointer
ios::end
end of the file
example:
file.seekg(-10, ios::cur);

Read & Write Example:


Following is the C++ program which opens a file in reading and writing mode. After writing
information inputted by the user to a file named afile.dat, the program reads information from the
file and outputs it onto the screen:
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{

char data[100];
// open a file in write mode.
ofstream outfile;
outfile.open("afile.dat");
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// write inputted data into the file.
outfile << data << endl;
cout << "Enter your age: ";
cin >> data;
cin.ignore();
// again write inputted data into the file.
outfile << data << endl;
// close the opened file.
outfile.close();
// open a file in read mode.
ifstream infile;
infile.open("afile.dat");
cout << "Reading from the file" << endl;
infile >> data;
// write the data at the screen.
cout << data << endl;
// again read the data from the file and display it.
infile >> data;
cout << data << endl;
// close the opened file.
infile.close();
return 0;
}
When the above code is compiled and executed, it produces the following sample input and
output:
$./a.out

Writing to the file


Enter your name: Zara
Enter your age: 9
Reading from the file
Zara
How is an Exception Handle in c++? Explain with suitable example?

An exception is a problem that arises during the execution of a program. A C++ exception is a
response to an exceptional circumstance that arises while a program is running, such as an
attempt to divide by zero.
Exceptions provide a way to transfer control from one part of a program to another. C++
exception handling is built upon three keywords: try, catch, and throw.
throw: A program throws an exception when a problem shows up. This is done using
a throwkeyword.
catch: A program catches an exception with an exception handler at the place in a
program where you want to handle the problem. The catch keyword indicates the catching of an
exception.
try: A try block identifies a block of code for which particular exceptions will be
activated. It's followed by one or more catch blocks.
Assuming a block will raise an exception, a method catches an exception using a combination of
thetry and catch keywords. A try/catch block is placed around the code that might generate an
exception. Code within a try/catch block is referred to as protected code, and the syntax for using
try/catch looks like the following:
try
{
// protected code
}catch( ExceptionName e1 )
{
// catch block
}catch( ExceptionName e2 )
{
// catch block
}catch( ExceptionName eN )
{
// catch block
}
You can list down multiple catch statements to catch different type of exceptions in case
your try block raises more than one exception in different situations.
Throwing Exceptions:
Exceptions can be thrown anywhere within a code block using throw statements. The operand of
the throw statements determines a type for the exception and can be any expression and the type
of the result of the expression determines the type of exception thrown.
Following is an example of throwing an exception when dividing by zero condition occurs:

double division(int a, int b)


{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
Catching Exceptions:
The catch block following the try block catches any exception. You can specify what type of
exception you want to catch and this is determined by the exception declaration that appears in
parentheses following the keyword catch.
try
{
// protected code
}catch( ExceptionName e )
{
// code to handle ExceptionName exception
}
Above code will catch an exception of ExceptionName type. If you want to specify that a catch
block should handle any type of exception that is thrown in a try block, you must put an ellipsis,
..., between the parentheses enclosing the exception declaration as follows:
try
{
// protected code
}catch(...)
{
// code to handle any exception
}
The following is an example, which throws a division by zero exception and we catch it in catch
block.
#include <iostream>
using namespace std;
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}

int main ()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
Because we are raising an exception of type const char*, so while catching this exception, we
have to use const char* in catch block. If we compile and run above code, this would produce the
following result:
Division by zero condition!
C++ Standard Exceptions:
C++ provides a list of standard exceptions defined in <exception> which we can use in our
programs. These are arranged in a parent-child class hierarchy shown below:
Here is the small description of each exception mentioned in the above hierarchy:
Exception

Description

std::exception

An exception and parent class of all the standard C++


exceptions.

std::bad_alloc

This can be thrown by new.

std::bad_cast

This can be thrown by dynamic_cast.

std::bad_exception

This is useful device to handle unexpected exceptions in a


C++ program

std::bad_typeid

This can be thrown by typeid.

std::logic_error

An exception that theoretically can be detected by reading the


code.

std::domain_error

This is an exception thrown when a mathematically invalid


domain is used

std::invalid_argument This is thrown due to invalid arguments.


std::length_error

This is thrown when a too big std::string is created

std::out_of_range

This can be thrown by the at method from for example a


std::vector and std::bitset<>::operator[]().

std::runtime_error

An exception that theoretically can not be detected by reading


the code.

std::overflow_error

This is thrown if a mathematical overflow occurs.

std::range_error

This is occured when you try to store a value which is out of


range.

std::underflow_error

This is thrown if a mathematical underflow occurs.

Define New Exceptions:


You can define your own exceptions by inheriting and overriding exception class functionality.
Following is the example, which shows how you can use std::exception class to implement your
own exception in standard way:
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception
{
const char * what () const throw ()
{
return "C++ Exception";
}
};
int main()
{
try
{
throw MyException();
}
catch(MyException& e)
{
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
}
catch(std::exception& e)
{
//Other errors
}
}
This would produce the following result:

MyException caught
C++ Exception
Here, what() is a public method provided by exception class and it has been overridden by all the
child exception classes. This returns the cause of an exception.
Wap to demonstrate overloading of operator + to add 2 complex number using friend
function?
Some of the most commonly used operators in C++ are the arithmetic operators that is, the
plus operator (+), minus operator (-), multiplication operator (*), and division operator (/). Note
that all of the arithmetic operators are binary operators meaning they take two operands
one on each side of the operator. All four of these operators are overloaded in the exact same
way.
Overloading operators using friend functions
When the operator does not modify its operands, the best way to overload the operator is via
friend function. None of the arithmetic operators modify their operands (they just produce and
return a result), so we will utilize the friend function overloaded operator method here.
The following example shows how to overload operator plus (+) in order to add two Cents
objects together:
Operators can be overloaded in c++ with friend functions also. The procedure is same as we
discussed earlier. Here I will demonstrate operator overloading with "+" operator which is a
binary operator. I will be using a complex number class (called complex). The class will have 2
data types, real and imaginary.
Operator overloading will not be a part of class complex, but we will declare that this function is
a friend of class complex.
Note that since overloaded function is not part of class , so will require 2 args (overloading with
member function require 1 arg for binary operator, as the first arg is the object itself.)
Use:
Most student wonder why we need to use operator overloading in such manner? The answer is
simple, this will allow you to manipulate operator for predefined objects that you mat not have
access. (Like cout or cin)
Code:
#include<iostream>
using namespace std;
// complex class with real and imaginary part
class complex
{
public:
int real;
int img;
//default constructor

complex()
{
real=img=0;
}
//overloaded constructor with 2 args
complex(int x,int y)
{
real=x;
img=y;
}
//show function to display complex number
void show()
{
cout<<"\n"<<real<<"+"<<img<<"i";
}
//declaring that "opeartor+" is friend of class complex
friend complex operator+(complex c,complex d);
};
//operator+ is not part of complex class so have 2 args for + operator overload.
complex operator+(complex c, complex f)
{
complex ans;
ans.real=c.real+f.real;
ans.img=c.img+f.img;
return(ans);
}
int main()
{
complex x(1,2), y(0,7);
complex c=x+y;//overloaded + is called here
//note that compiler will convert this to
// c=operator+(x,y)
c.show();
}

Explain the difference between overloading and overriding?


Overloading is defining functions that have similar signatures, yet have different parameters.
Overriding is only pertinent to derived classes, where the parent class has defined a method and
the derived class wishes to override that function.
Overriding

Overloading

Methods name and signatures must be same.


Overriding is the concept of runtime
polymorphism
When a function of base class is re-defined in
the derived class called as Overriding
It needs inheritance.
Method should have same data type.
Method should be public.

Having same method name with different


Signatures.
Overloading is the concept of compile time
polymorphism
Two functions having same name and return
type, but with different type and/or number of
arguments is called as Overloading
It doesn't need inheritance.
Method can have different data types
Method can be different access specifies

Example
Overriding
public class MyBaseClass
{
public virtual void MyMethod()
{
Console.Write("My BaseClass Method");
}
}
public class MyDerivedClass : MyBaseClass
{
public override void MyMethod()
{
Console.Write("My DerivedClass Method");
}
}
Overloading
int add(int a, int b)
int add(float a , float b)

Explain the concepts of oops supported by example?

In this tutorial you will learn about Objects, Classes, Inheritance, Data Abstraction, Data
Encapsulation, Polymorphism, Overloading, and Reusability.
Before starting to learn C++ it is essential to have a basic knowledge of the concepts of Object
oriented programming. Some of the important object oriented features are namely:
Objects

Classes

Inheritance

Data Abstraction

Data Encapsulation

Polymorphism

Overloading

Reusability
In order to understand the basic concepts in C++, a programmer must have a good knowledge of
the basic terminology in object-oriented programming. Below is a brief outline of the concepts of
object-oriented programming languages :

Objects:
Object is the basic unit of object-oriented programming. Objects are identified by its unique
name. An object represents a particular instance of a class. There can be more than one instance
of a class. Each instance of a class can hold its own relevant data.

An Object is a collection of data members and associated member functions also known as
methods.
Classes:
Classes are data types based on which objects are created. Objects with similar properties and
methods are grouped together to form a Class. Thus a Class represents a set of individual objects.

Characteristics of an object are represented in a class as Properties. The actions that can be
performed by objects become functions of the class and are referred to as Methods.
For example consider we have a Class of Cars under which Santro Xing, Alto and WaganR
represents individual Objects. In this context each Car Object will have its own, Model, Year of
Manufacture, Color, Top Speed, Engine Power etc., which form Properties of the Car class and
the associated actions i.e., object functions like Start, Move, and Stop form the Methods of Car
Class.
No memory is allocated when a class is created. Memory is allocated only when an object is
created, i.e., when an instance of a class is created.
Inheritance:
Inheritance is the process of forming a new class from an existing class or base class. The base
class is also known as parent class or super class. The new class that is formed is called derived
class. Derived class is also known as a child class or sub class. Inheritance helps in reducing the
overall code size of the program, which is an important concept in object-oriented programming.
Data Abstraction:
Data Abstraction increases the power of programming language by creating user defined data
types. Data Abstraction also represents the needed information in the program without presenting
the details.
Data Encapsulation:
Data Encapsulation combines data and functions into a single unit called Class. When using Data
Encapsulation, data is not accessed directly; it is only accessible through the functions present
inside the class. Data Encapsulation enables the important concept of data hiding possible.
Polymorphism:
Polymorphism allows routines to use variables of different types at different times. An operator
or function can be given different meanings or functions. Polymorphism refers to a single
function or multi-functioning operator performing in different ways.
Overloading:
Overloading is one type of Polymorphism. It allows an object to have different meanings,
depending on its context. When an existing operator or function begins to operate on new data
type, or class, it is understood to be overloaded.

Reusability:
This term refers to the ability for multiple programmers to use the same written and debugged
existing class of data. This is a time saving device and adds code efficiency to the language.
Additionally, the programmer can incorporate new features to the existing class, further
developing the application and allowing users to achieve increased performance. This time
saving feature optimizes code, helps in gaining secured applications and facilitates easier
maintenance on the application.
The implementation of each of the above object-oriented programming features for C++ will be
highlighted in later sections.
A sample program to understand the basic structure of C++
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.

//program to read employee details and to output the data


////////// code begins here /////////////////////////////
// Preprocessor directive
#include < iostream >
using namespace std;
class employee
// Class Declaration
{
private:
char empname[50];
int empno;
public:

void getvalue()
{
cout<<"INPUT Employee Name:";
cin>>empname;
//
waiting input from the Keyboard for the name
17.
cout<<"INPUT Employee Number:";
18.
cin>>empno;
// waiting
input from the Keyboard for the number
19.
}
20.
void displayvalue(){
21.
cout<<"Employee Name:"<< empname << endl; // displays the
employee name
22.
cout<<"Employee Number:"<< empno << endl; // displays the
emloyee number

23.
24.
25.
26.
27.
28.
29.

};
void main()
{
employee e1;
// Creation of Object
e1.getvalue();
// the getvalue method is
being called
30.
e1.displayvalue(); // the displayvalue method is being called
31.
}
32.
33.
///// code ends here //////////////
Output:

Data Encapsulation
All C++ programs are composed of the following two fundamental elements:

Program statements (code): This is the part of a program that performs actions and they
are called functions.
Program data: The data is the information of the program which affected by the
program functions.
Encapsulation is an Object Oriented Programming concept that binds together the data and
functions that manipulate the data, and that keeps both safe from outside interference and misuse.
Data encapsulation led to the important OOP concept of data hiding.
Data encapsulation is a mechanism of bundling the data, and the functions that use them
and data abstraction is a mechanism of exposing only the interfaces and hiding the
implementation details from the user.
C++ supports the properties of encapsulation and data hiding through the creation of userdefined types, called classes. We already have studied that a class can contain private,
protected and publicmembers. By default, all items defined in a class are private. For example:
class Box

{
public:
double getVolume(void)
{
return length * breadth * height;
}
private:
double length;
// Length of a box
double breadth; // Breadth of a box
double height;
// Height of a box
};
The variables length, breadth, and height are private. This means that they can be accessed only
by other members of the Box class, and not by any other part of your program. This is one way
encapsulation is achieved.
To make parts of a class public (i.e., accessible to other parts of your program), you must declare
them after the public keyword. All variables or functions defined after the public specifier are
accessible by all other functions in your program.
Making one class a friend of another exposes the implementation details and reduces
encapsulation. The ideal is to keep as many of the details of each class hidden from all other
classes as possible.
Data Encapsulation Example:
Any C++ program where you implement a class with public and private members is an example
of data encapsulation and data abstraction. Consider the following example:
#include <iostream>
using namespace std;
class Adder{
public:
// constructor
Adder(int i = 0)
{
total = i;
}
// interface to outside world
void addNum(int number)
{
total += number;
}
// interface to outside world
int getTotal()
{
return total;

};
private:
// hidden data from outside world
int total;
};
int main( )
{
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
cout << "Total " << a.getTotal() <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Total 60
Above class adds numbers together, and returns the sum. The public
members addNum and getTotalare the interfaces to the outside world and a user needs to know
them to use the class. The private member total is something that is hidden from the outside
world, but is needed for the class to operate properly.
Designing Strategy:
Most of us have learned through bitter experience to make class members private by default
unless we really need to expose them. That's just good encapsulation.
This wisdom is applied most frequently to data members, but it applies equally to all members,
including virtual functions.

Classes & Objects

he main purpose of C++ programming is to add object orientation to the C programming


language and classes are the central feature of C++ that supports object-oriented programming
and are often called user-defined types.
A class is used to specify the form of an object and it combines data representation and methods
for manipulating that data into one neat package. The data and functions within a class are called
members of the class.
C++ Class Definitions:

When you define a class, you define a blueprint for a data type. This doesn't actually define any
data, but it does define what the class name means, that is, what an object of the class will consist
of and what operations can be performed on such an object.
A class definition starts with the keyword class followed by the class name; and the class body,
enclosed by a pair of curly braces. A class definition must be followed either by a semicolon or a
list of declarations. For example, we defined the Box data type using the keyword class as
follows:
class Box
{
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
The keyword public determines the access attributes of the members of the class that follow it. A
public member can be accessed from outside the class anywhere within the scope of the class
object. You can also specify the members of a class as private or protected which we will
discuss in a sub-section.
Define C++ Objects:
A class provides the blueprints for objects, so basically an object is created from a class. We
declare objects of a class with exactly the same sort of declaration that we declare variables of
basic types. Following statements declare two objects of class Box:
Box Box1;
Box Box2;

// Declare Box1 of type Box


// Declare Box2 of type Box

Both of the objects Box1 and Box2 will have their own copy of data members.
Accessing the Data Members:
The public data members of objects of a class can be accessed using the direct member access
operator (.). Let us try the following example to make the things clear:
#include <iostream>
using namespace std;
class Box
{
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box

};
int main( )
{
Box Box1;
// Declare Box1 of type Box
Box Box2;
// Declare Box2 of type Box
double volume = 0.0; // Store the volume of a box here
// box 1 specification
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
// box 2 specification
Box2.height = 10.0;
Box2.length = 12.0;
Box2.breadth = 13.0;
// volume of box 1
volume = Box1.height * Box1.length * Box1.breadth;
cout << "Volume of Box1 : " << volume <<endl;
// volume of box 2
volume = Box2.height * Box2.length * Box2.breadth;
cout << "Volume of Box2 : " << volume <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Volume of Box1 : 210
Volume of Box2 : 1560
It is important to note that private and protected members can not be accessed directly using
direct member access operator (.). We will learn how private and protected members can be
accessed.
Classes & Objects in Detail:
So far, you have got very basic idea about C++ Classes and Objects. There are further interesting
concepts related to C++ Classes and Objects which we will discuss in various sub-sections listed
below:
Concept

Description

Class member functions

A member function of a class is a function that has


its definition or its prototype within the class
definition like any other variable.

Class access modifiers

A class member can be defined as public, private


or protected. By default members would be
assumed as private.

Constructor & destructor

A class constructor is a special function in a class


that is called when a new object of the class is
created. A destructor is also a special function
which is called when created object is deleted.

C++ copy constructor

The copy constructor is a constructor which


creates an object by initializing it with an object of
the same class, which has been created previously.

C++ friend functions

A friend function is permitted full access to


private and protected members of a class.

C++ inline functions

With an inline function, the compiler tries to


expand the code in the body of the function in
place of a call to the function.

The this pointer in C++

Every object has a special pointer this which


points to the object itself.

Pointer to C++ classes

A pointer to a class is done exactly the same way a


pointer to a structure is. In fact a class is really just
a structure with functions in it.

Static members of a class

Both data members and function members of a


class can be declared as static.

Inheritance
One of the most important concepts in object-oriented programming is that of inheritance.
Inheritance allows us to define a class in terms of another class, which makes it easier to create

and maintain an application. This also provides an opportunity to reuse the code functionality
and fast implementation time.
When creating a class, instead of writing completely new data members and member functions,
the programmer can designate that the new class should inherit the members of an existing class.
This existing class is called the base class, and the new class is referred to as the derived class.
The idea of inheritance implements the is a relationship. For example, mammal IS-A animal, dog
IS-A mammal hence dog IS-A animal as well and so on.
Base & Derived Classes:
A class can be derived from more than one classes, which means it can inherit data and functions
from multiple base classes. To define a derived class, we use a class derivation list to specify the
base class(es). A class derivation list names one or more base classes and has the form:
class derived-class: access-specifier base-class
Where access-specifier is one of public, protected, or private, and base-class is the name of a
previously defined class. If the access-specifier is not used, then it is private by default.
Consider a base class Shape and its derived class Rectangle as follows:
#include <iostream>
using namespace std;
// Base class
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// Derived class
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);

}
};
int main(void)
{
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Total area: 35
Access Control and Inheritance:
A derived class can access all the non-private members of its base class. Thus base-class
members that should not be accessible to the member functions of derived classes should be
declared private in the base class.
We can summarize the different access types according to who can access them in the following
way:
Access

public

protected

private

Same class

yes

yes

yes

Derived classes

yes

yes

no

Outside classes

yes

no

no

A derived class inherits all base class methods with the following exceptions:

Constructors, destructors and copy constructors of the base class.

Overloaded operators of the base class.

The friend functions of the base class.


Type of Inheritance:

When deriving a class from a base class, the base class may be inherited through public,
protected orprivate inheritance. The type of inheritance is specified by the access-specifier as
explained above.
We hardly use protected or private inheritance, but public inheritance is commonly used.
While using different type of inheritance, following rules are applied:
Public Inheritance: When deriving a class from a public base class, public members of
the base class become public members of the derived class and protected members of the base
class become protected members of the derived class. A base class's private members are never
accessible directly from a derived class, but can be accessed through calls to
the publicand protected members of the base class.
Protected
Inheritance: When
deriving
from
a protected base
class, public and protectedmembers of the base class become protected members of the derived
class.
Private
Inheritance: When
deriving
from
a private base
class, public and protected members of the base class become private members of the derived
class.
Multiple Inheritances:
A C++ class can inherit members from more than one class and here is the extended syntax:
class derived-class: access baseA, access baseB....
Where access is one of public, protected, or private and would be given for every base class
and they will be separated by comma as shown above. Let us try the following example:
#include <iostream>
using namespace std;
// Base class Shape
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// Base class PaintCost

class PaintCost
{
public:
int getCost(int area)
{
return area * 70;
}
};
// Derived class
class Rectangle: public Shape, public PaintCost
{
public:
int getArea()
{
return (width * height);
}
};
int main(void)
{
Rectangle Rect;
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
// Print the total cost of painting
cout << "Total paint cost: $" << Rect.getCost(area) << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Total area: 35
Total paint cost: $2450

Oveloading Operator & Function


C++ allows you to specify more than one definition for a function name or an operator in the
same scope, which is called function overloading and operator overloading respectively.
An overloaded declaration is a declaration that had been declared with the same name as a
previously declared declaration in the same scope, except that both declarations have different
arguments and obviously different definition (implementation).
When you call an overloaded function or operator, the compiler determines the most
appropriate definition to use by comparing the argument types you used to call the function or
operator with the parameter types specified in the definitions. The process of selecting the most
appropriate overloaded function or operator is called overload resolution.
Function overloading in C++:
You can have multiple definitions for the same function name in the same scope. The definition
of the function must differ from each other by the types and/or the number of arguments in the
argument list. You can not overload function declarations that differ only by return type.
Following is the example where same function print() is being used to print different data types:
#include <iostream>
using namespace std;
class printData
{
public:
void print(int i) {
cout << "Printing int: " << i << endl;
}
void print(double f) {
cout << "Printing float: " << f << endl;
}
void print(char* c) {
cout << "Printing character: " << c << endl;
}
};
int main(void)
{
printData pd;
// Call print to print integer
pd.print(5);
// Call print to print float
pd.print(500.263);

// Call print to print character


pd.print("Hello C++");
return 0;
}
When the above code is compiled and executed, it produces the following result:
Printing int: 5
Printing float: 500.263
Printing character: Hello C++
Operators overloading in C++:
You can redefine or overload most of the built-in operators available in C++. Thus a programmer
can use operators with user-defined types as well.
Overloaded operators are functions with special names the keyword operator followed by the
symbol for the operator being defined. Like any other function, an overloaded operator has a
return type and a parameter list.
Box operator+(const Box&);
declares the addition operator that can be used to add two Box objects and returns final Box
object. Most overloaded operators may be defined as ordinary non-member functions or as class
member functions. In case we define above function as non-member function of a class then we
would have to pass two arguments for each operand as follows:
Box operator+(const Box&, const Box&);
Following is the example to show the concept of operator over loading using a member function.
Here an object is passed as an argument whose properties will be accessed using this object, the
object which will call this operator can be accessed using this operator as explained below:
#include <iostream>
using namespace std;
class Box
{
public:
double getVolume(void)
{
return length * breadth * height;
}
void setLength( double len )
{
length = len;
}

void setBreadth( double bre )


{
breadth = bre;
}
void setHeight( double hei )
{
height = hei;
}
// Overload + operator to add two Box objects.
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
private:
double length;
// Length of a box
double breadth; // Breadth of a box
double height;
// Height of a box
};
// Main function for the program
int main( )
{
Box Box1;
// Declare Box1 of type Box
Box Box2;
// Declare Box2 of type Box
Box Box3;
// Declare Box3 of type Box
double volume = 0.0; // Store the volume of a box here
// box 1 specification
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// box 2 specification
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// volume of box 1
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;

// volume of box 2
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
// Add two object as follows:
Box3 = Box1 + Box2;
// volume of box 3
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400
Overloadable/Non-overloadableOperators:
Following is the list of operators which can be overloaded:
+

&

<

>

<=

>=

++

--

<<

>>

==

!=

&&

||

+=

-=

/=

%=

^=

&=

|=

*=

<<=

>>=

[]

()

->

->*

new

new []

delete

delete []

Following is the list of operators, which can not be overloaded:


::

.*

?:

PolyMorphism
The word polymorphism means having many forms. Typically, polymorphism occurs when
there is a hierarchy of classes and they are related by inheritance.

C++ polymorphism means that a call to a member function will cause a different function to be
executed depending on the type of object that invokes the function.
Consider the following example where a base class has been derived by other two classes:
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// Main function for the program
int main( )
{
Shape *shape;
Rectangle rec(10,7);

Triangle tri(10,5);
// store the address of Rectangle
shape = &rec;
// call rectangle area.
shape->area();
// store the address of Triangle
shape = &tri;
// call triangle area.
shape->area();
return 0;
}
When the above code is compiled and executed, it produces the following result:
Parent class area
Parent class area
The reason for the incorrect output is that the call of the function area() is being set once by the
compiler as the version defined in the base class. This is called static resolution of the function
call, orstatic linkage - the function call is fixed before the program is executed. This is also
sometimes calledearly binding because the area() function is set during the compilation of the
program.
But now, let's make a slight modification in our program and precede the declaration of area() in
the Shape class with the keyword virtual so that it looks like this:
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
After this slight modification, when the previous example code is compiled and executed, it
produces the following result:

Rectangle class area


Triangle class area
This time, the compiler looks at the contents of the pointer instead of it's type. Hence, since
addresses of objects of tri and rec classes are stored in *shape the respective area() function is
called.
As you can see, each of the child classes has a separate implementation for the function area().
This is how polymorphism is generally used. You have different classes with a function of the
same name, and even the same parameters, but with different implementations.
Virtual Function:
A virtual function is a function in a base class that is declared using the keyword virtual.
Defining in a base class a virtual function, with another version in a derived class, signals to the
compiler that we don't want static linkage for this function.
What we do want is the selection of the function to be called at any given point in the program to
be based on the kind of object for which it is called. This sort of operation is referred to
as dynamic linkage, or late binding.
Pure Virtual Functions:
It's possible that you'd want to include a virtual function in a base class so that it may be
redefined in a derived class to suit the objects of that class, but that there is no meaningful
definition you could give for the function in the base class.
We can change the virtual function area() in the base class to the following:
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;
};
The = 0 tells the compiler that the function has no body and above virtual function will be
called pure virtual function.

Data Abstraction

Data abstraction refers to, providing only essential information to the outside world and hiding
their background details, i.e., to represent the needed information in program without presenting
the details.
Data abstraction is a programming (and design) technique that relies on the separation of
interface and implementation.
Let's take one real life example of a TV, which you can turn on and off, change the channel,
adjust the volume, and add external components such as speakers, VCRs, and DVD players,
BUT you do not know its internal details, that is, you do not know how it receives signals over
the air or through a cable, how it translates them, and finally displays them on the screen.
Thus, we can say a television clearly separates its internal implementation from its external
interface and you can play with its interfaces like the power button, channel changer, and volume
control without having zero knowledge of its internals.
Now, if we talk in terms of C++ Programming, C++ classes provides great level of data
abstraction. They provide sufficient public methods to the outside world to play with the
functionality of the object and to manipulate object data, i.e., state without actually knowing how
class has been implemented internally.
For example, your program can make a call to the sort() function without knowing what
algorithm the function actually uses to sort the given values. In fact, the underlying
implementation of the sorting functionality could change between releases of the library, and as
long as the interface stays the same, your function call will still work.
In C++, we use classes to define our own abstract data types (ADT). You can use the cout object
of class ostream to stream data to standard output like this:
#include <iostream>
using namespace std;
int main( )
{
cout << "Hello C++" <<endl;
return 0;
}
Here, you don't need to understand how cout displays the text on the user's screen. You need to
only know the public interface and the underlying implementation of cout is free to change.
Access Labels Enforce Abstraction:
In C++, we use access labels to define the abstract interface to the class. A class may contain
zero or more access labels:

Members defined with a public label are accessible to all parts of the program. The dataabstraction view of a type is defined by its public members.

Members defined with a private label are not accessible to code that uses the class. The
private sections hide the implementation from code that uses the type.

There are no restrictions on how often an access label may appear. Each access label specifies
the access level of the succeeding member definitions. The specified access level remains in
effect until the next access label is encountered or the closing right brace of the class body is
seen.
Benefits of Data Abstraction:
Data abstraction provides two important advantages:

Class internals are protected from inadvertent user-level errors, which might corrupt the
state of the object.

The class implementation may evolve over time in response to changing requirements or
bug reports without requiring change in user-level code.
By defining data members only in the private section of the class, the class author is free to make
changes in the data. If the implementation changes, only the class code needs to be examined to
see what affect the change may have. If data are public, then any function that directly accesses
the data members of the old representation might be broken.
Data Abstraction Example:
Any C++ program where you implement a class with public and private members is an example
of data abstraction. Consider the following example:
#include <iostream>
using namespace std;
class Adder{
public:
// constructor
Adder(int i = 0)
{
total = i;
}
// interface to outside world
void addNum(int number)
{
total += number;
}
// interface to outside world
int getTotal()
{
return total;
};
private:
// hidden data from outside world

int total;
};
int main( )
{
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
cout << "Total " << a.getTotal() <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Total 60
Above class adds numbers together, and returns the sum. The public
members addNum and getTotalare the interfaces to the outside world and a user needs to know
them to use the class. The private member total is something that the user doesn't need to know
about, but is needed for the class to operate properly.
Designing Strategy:
Abstraction separates code into interface and implementation. So while designing your
component, you must keep interface independent of the implementation so that if you change
underlying implementation then interface would remain intact.
In this case whatever programs are using these interfaces, they would not be impacted and would
just need a recompilation with the latest implementation.

InterFace

An interface describes the behavior or capabilities of a C++ class without committing to a


particular implementation of that class.
The C++ interfaces are implemented using abstract classes and these abstract classes should not
be confused with data abstraction which is a concept of keeping implementation details separate
from associated data.
A class is made abstract by declaring at least one of its functions as pure virtual function. A
pure virtual function is specified by placing "= 0" in its declaration as follows:
class Box
{

public:
// pure virtual function
virtual double getVolume() = 0;
private:
double length;
// Length of a box
double breadth; // Breadth of a box
double height;
// Height of a box
};
The purpose of an abstract class (often referred to as an ABC) is to provide an appropriate base
class from which other classes can inherit. Abstract classes cannot be used to instantiate objects
and serves only as an interface. Attempting to instantiate an object of an abstract class causes a
compilation error.
Thus, if a subclass of an ABC needs to be instantiated, it has to implement each of the virtual
functions, which means that it supports the interface declared by the ABC. Failure to override a
pure virtual function in a derived class, then attempting to instantiate objects of that class, is a
compilation error.
Classes that can be used to instantiate objects are called concrete classes.
Abstract Class Example:
Consider the following example where parent class provides an interface to the base class to
implement a function called getArea():
#include <iostream>
using namespace std;
// Base class
class Shape
{
public:
// pure virtual function providing interface framework.
virtual int getArea() = 0;
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};

// Derived classes
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};
class Triangle: public Shape
{
public:
int getArea()
{
return (width * height)/2;
}
};
int main(void)
{
Rectangle Rect;
Triangle Tri;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object.
cout << "Total Rectangle area: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
// Print the area of the object.
cout << "Total Triangle area: " << Tri.getArea() << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Total Rectangle area: 35
Total Triangle area: 17
You can see how an abstract class defined an interface in terms of getArea() and two other
classes implemented same function but with different algorithm to calculate the area specific to
the shape.
Designing Strategy:

An object-oriented system might use an abstract base class to provide a common and
standardized interface appropriate for all the external applications. Then, through inheritance
from that abstract base class, derived classes are formed that all operate similarly.
The capabilities (i.e., the public functions) offered by the external applications are provided as
pure virtual functions in the abstract base class. The implementations of these pure virtual
functions are provided in the derived classes that correspond to the specific types of the
application.
This architecture also allows new applications to be added to a system easily, even after the
system has been defined.

Explain the new and delete operator in dynamic memory allocation?


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.
If you are not in need of dynamically allocated memory anymore, you can use delete operator,
which de-allocates memory previously allocated by 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 newoperator with the following statements:
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable
The memory may not have been allocated successfully, if the free store had been used up. So it is
good practice to check if new operator is returning NULL pointer and take appropriate action as
below:

double* pvalue = NULL;


if( !(pvalue = new double ))
{
cout << "Error: out of memory." <<endl;
exit(1);
}
The malloc() function from C, still exists in C++, but it is recommended to avoid using malloc()
function. The main advantage of new over malloc() is that new doesn't just allocate memory, it
constructs objects which is prime purpose of C++.
At any point, when you feel a variable that has been dynamically allocated is not anymore
required, you can free up the memory that it occupies in the free store with the delete operator as
follows:
delete pvalue;

// Release memory pointed to by pvalue

Let us put above concepts and form the following example to show how new and delete work:
#include <iostream>
using namespace std;
int main ()
{
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable
*pvalue = 29494.99; // Store value at allocated address
cout << "Value of pvalue : " << *pvalue << endl;
delete pvalue;

// free up the memory.

return 0;
}
If we compile and run above code, this would produce the following result:
Value of pvalue : 29495
Dynamic Memory Allocation for Arrays:
Consider you want to allocate memory for an array of characters, i.e., string of 20 characters.
Using the same syntax what we have used above we can allocate memory dynamically as shown
below.
char* pvalue = NULL; // Pointer initialized with null

pvalue = new char[20]; // Request memory for the variable


To remove the array that we have just created the statement would look like this:
delete [] pvalue;

// Delete array pointed to by pvalue

Following the similar generic syntax of new operator, you can allocat for a multi-dimensional
array as follows:
double** pvalue = NULL; // Pointer initialized with null
pvalue = new double [3][4]; // Allocate memory for a 3x4 array
However, the syntax to release the memory for multi-dimensional array will still remain same as
above:
delete [] pvalue;

// Delete array pointed to by pvalue

Dynamic Memory Allocation for Objects:


Objects are no different from simple data types. For example, consider the following code where
we are going to use an array of objects to clarify the concept:
#include <iostream>
using namespace std;
class Box
{
public:
Box() {
cout << "Constructor called!" <<endl;
}
~Box() {
cout << "Destructor called!" <<endl;
}
};
int main( )
{
Box* myBoxArray = new Box[4];
delete [] myBoxArray; // Delete array
return 0;
}

If you were to allocate an array of four Box objects, the Simple constructor would be called four
times and similarly while deleting these objects, destructor will also be called same number of
times.
If we compile and run above code, this would produce the following result:
Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!

Wap to read 2 integer from keyboard and to perform simple airthematic operation using
the pointer technique?The memory space for the operator is allocated by the new
operator?

Wap a program to define a class vector that operates on vector. write the member function
to compute the vector product, scalar product ,sum of the element of the vector, average of
elements, and sum of the square of elements?

What is containership? How does it differ from inheritance?


Inheritance vs Containership
Inheritance and Containership are two important concepts found in OOP (Object Oriented
Programming Example: C++). In simple terms, both Containership and Inheritance deal with
providing additional properties or behavior to a class. Inheritance is the ability for a class to
inherit properties and behavior from a parent class by extending it. On the other hand,
Containership is the ability of a class to contain objects of different classes as member data.
What is Inheritance?
As mentioned above, Inheritance is the ability for a class to inherit properties and behavior from
a parent class by extending it. Inheritance essentially provides code reuse by allowing extending
properties and behavior of an existing class by a newly defined class. If class A extends B, then
class B is called the parent class (or super class) and class A is called the child class (or derived

class/sub class). In this example scenario, class A will inherit all public and protected attributes
and methods of the super class (B). The subclass can optionally override (provide new or
extended functionality to methods) the behavior inherited from the parent class. Inheritance
represents an is-a relationship in OOP. This essentially means that A is also a B. In other
words, B can be the class with a general description of a certain real world entity but A specifies
a certain specialization. In a real world programming problem, the Person class could be
extended to create the Employee class. This is called specialization. But you could also first
create the Employee class and then generalize it to a Person class as well (i.e. generalization). In
this example, the Employee will have all the properties and behavior of the Person (i.e.
Employee is also a Person) and may contain some additional functionality (so, Person is not an
Employee) as well.
What is Containership?
Containership is the ability of a class to contain objects of different classes as member data. For
example, class A could contain an object of class B as a member. Here, all the public methods
(or functions) defined in B can be executed within the class A. Class A becomes the container,
while class B becomes the contained class. Containership is also referred to as Composition. In
this example, it can be said that class A is composed of class B. In OOP, Containership
represents a has-a relationship. It is important to note that, even though the container has
access to execute all the public methods of the contained class, it is not able to alter or provide
additional functionality. When it comes to a real world programming problem, an object of class
TextBox may be contained in the class Form, and thus can be said that a Form contains a
TextBox (or alternatively, a Form is composed of a TextBox).
Difference between Inheritance and Containership
Although Inheritance and Containership are two OOP concepts, they are quite different in what
they allow the programmer to achieve. Inheritance is the ability for a class to inherit properties
and behavior from a parent class by extending it, while Containership is the ability of a class to
contain objects of different classes as member data. If a class is extended, it inherits all the public
and protected properties/behavior and those behaviors may be overridden by the subclass. But if
a class is contained in another, the container does not get the ability to change or add behavior to
the contained. Inheritance represents an is-a relationship in OOP, while Containership
represents a has-a relationship.

Differentiate between class and Objects?


Objects vs Classes

Objects and classes are used in object oriented programming languages. All object oriented
programming languages such as C++, Java, .NET and others, employs objects and classes.
Objects
An object is defined as any entity that can be utilized by using commands in a programming
language. Object can be a variable, value, data structure or a function. In object oriented
environment, object is referred to as instance of a class. Objects and classes are closely related to
each other. In real world, the objects are your TV, bicycle, desk and other entities. Methods are
used to access the objects of a class. All the interaction is done through the objects methods.
This is known as data encapsulation. The objects are also used for data or code hiding.
A number of benefits are provided by the objects when they are used in the code:
Ease of debugging The object can be easily removed from the code if there is some problem
due to it. A different object can be plugged in as a replacement of the former one.
Information hiding The code or internal implementation is hidden from the users when
interaction is done through objects methods.
Reuse of code if an object or code is written by some other programmer then you can also use
that object in your program. In this way, objects are highly reusable. This allows experts to
debug, implement task specific and complex objects that can be used in your own code.
Modularity You can write as well as maintain the source codes of objects in an independent
manner. This provides modular approach to programming.
Classes
A class is a concept used in object oriented programming languages such as C++, PHP, and
JAVA etc. Apart from holding data, a class is also used to hold functions. An object is an instant
of a class. In case of variables, the type is the class whereas the variable is the object. The
keyword class is used to declare a class and it has the following format:
class CLASS_NAME
{
AccessSpecifier1:
Member-1;
AccessSpecifier2:
Member-2;

} OBJECT_NAMES;
Here, the valid identifier is CLASS_NAME and the names for objects are represented by
OBJECT_NAMES. The benefit of objects include information hiding, modularity, ease in
debugging and reuse of the code. The body contains the members that can be functions or data
declarations. The keywords for access specifiers are public, protected or private.

The public members can be accessed anywhere.


The protected members can be accessed within same classes or from friend classes.
The private members can be accessed only within the same class.
By default, the access is private when the class keyword is used. A class can hold both data and
functions.
Objects vs. Classes
An object is an instant of a class. A class is used to hold data and functions.
When a class is declared, no memory is allocated but when the object of the class is
declared, memory is allocated. So, class is just a template.
An object can only be created if the class is already declared otherwise it is not possible

Difference between containership and inheritance or derived class in C++


Containership: Containership is the phenomenon of using one or more classes within the
definition of other class. When a class contains the definition of some other classes, it is referred
to as composition, containment or aggregation. The data member of a new class is an object of
some other class. Thus the other class is said to be composed of other classes and hence referred
to as containership. Composition is often referred to as a has-a relationship because the
objects of the composite class have objects of the composed class as members.
What is a container class? What are the types of container classes?
A container class is a class that is used to hold objects in memory or external storage. A
container class acts as a generic holder. A container class has a predefined behavior and a wellknown interface. A container class is a supporting class whose purpose is to hide the topology
used for maintaining the list of objects in memory. When a container class contains a group of
mixed objects, the container is called a heterogeneous container; when the container is holding a
group of objects that are all the same, the container is called a homogeneous container.

Inheritance: Inheritance is the phenomenon of deriving a new class from an old one.
Inheritance supports code reusability. Additional features can be added to a class by deriving a
class from it and then by adding new features to it. Class once written or tested need not be
rewritten or redefined. Inheritance is also referred to as specialization or derivation, as one class
is inherited or derived from the other. It is also termed as is-a relationship because every
object of the class being defined is also an object of the inherited class.

How is polymorphism achieved in compile time and runtime?


Compile time Polymorphism:
C++ support polymorphism. One function multiple purpose, or in short many functions having
same name but with different function body.
For every function call compiler binds the call to one function definition at compile time. This
decision of binding among several functions is taken by considering formal arguments of the
function, their data type and their sequence.
Example of compile time polymorphism:
Example 1: example of compile time polymorphism; static time binding
void f(int i){cout<<"int";}
void f(char c){cout<<"char";}
int main()
{
f(10);
return 0;
}
Output: int

Run time polymorphism:


C++ allows binding to be delayed till run time. When you have a function with same name, equal
number of arguments and same data type in same sequence in base class as well derived class
and a function call of form: base_class_type_ptr->member_function(args); will always call base
class member function. The keyword virtual on a member function in base class indicates to the
compiler to delay the binding till run time.
Every class with atleast one virtual function has a vtable that helps in binding at run time.
Looking at the content of base class type pointer it will correctly call the member function of one
of possible derived / base class member function.
Example of run time polymorphism:
class Base
{
public:
virtual void display(int i)
{ cout<<"Base::"<<i; }
};

class Derv: public Base


{
public:
void display(int j)
{ cout<<"Derv::"<<j; }
};
int main()
{
Base *ptr=new Derv;
ptr->display(10);
return 0;
}
Output: Derv::10

Wap to using polymorphism that will accept a geometrical figure and displays its shaped and
calculates its area?

Explain the basic control structure in c++?


L STRUCTURES IN C++
Normally, statements in a program execute one after the other in the order in which they are
written. This is called sequential execution. Various C++ statements will enable you to specify
that the next statement to execute may other than the next one in sequence. This called transfer of
control. This is achieved by using a selection structure of repetition structure.
C++ provides three types of selection structure. The if selection structure either perform an
action if a condition is true, or skips the action if the condition is false. The if/else selection
structure performs an action if a condition is true, or performs a different action if the condition
is false. Theif selection structure is a single selection structure, it selects or ignores a single
action .The if/else selection structure is a double selection structure, it selects between two
different actions.
The switch selection structure performs one of many different actions, depending on the value of

an integer expression. The switch selection structure is a multiple selection structure, it selects
the action to perform from many different action states.
C++ provides three types of repetition structures also called looping structures or loops,
namely while, do/while, and for. A repetition structure allows the programmer to specify that a
program should repeat an action while some condition remains true.
posted by Carlos @ 1:30 PM
If Selection Structure
Programs use selection structures to choose among alternative courses of action. For example,
suppose the passing grade on exam is 60. The pseudo code statement
If students grade is greater than or equal to 60
Print Passed
Determines whether the condition "students" grade is greater than or equal to 60 is true or false.
If the condition is true, then "Passed" If the condition is false the print statement is ignored.
Example as follows
If single selection structure activity diagram

posted by Carlos @ 1:29 AM


if/else selection structure
The if selection structure performs an indicated action only when the condition is true otherwise
the action is skipped. The if/else selection structure allows the programmer to specify an action
to perform when the condition is true and a different action to perform when the condition is
false. For example, the pseudo code statement.

If students grade is greater than or equal to 60


Print Passed
else
Print Failed
Print Passed if the student's grade is greater than or equal to 60, but prints Failed if the
student's grade is less than 60. In either case, after printing occurs. the next pseudo code
statement in sequence is performed.
Example as follows
if/else double selection structure activity diagram

posted by Carlos @ 1:28 AM


switch Multiple Selection Structure
Occasionally, an algorithm will contain a series of decision in which a variable or expression is
tested separately for each of the constant integral values it can assume and different actions are
taken. C++ provides the switch multiple selection structure to handle such decision making. The
switch structure consists of a series of case labels and an optional default case
Example as follows
Switc selection structure activity diagram.

posted by Carlos @ 1:27 AM


while Repetition Structure
A repetition structure allows the programmer to specify that a program should repeat an action
while some condition remains true. The pseudo code statement
While there are more items on my shopping list
Purchase next item and cross it off my list
Describes the repetition that occurs during a shopping trip. The condition there are more items on
my shopping list is either true or false. if it is true, then the action purchase next item and cross it
off list is performed. This action will be performed repeatedly while the condition remains true.
Example as follows
while repetition structure activity diagram

posted by Carlos @ 1:26 AM


for Repetition Structure

The general format of the for structure is


for ( initialization; loopContinuationCondition; increment)
Statement
Where the initialization expression initializes the loop control variable, loopContinuation is the
condition that determines whether the loop should continue executing, and increment increments
the control variable. In most cases, the for structure can be represented by an equivalent while
structure, as follows:
Initialization;
while ( loop Continuation Condition) {
statement
increment;
}
Example as follows
for repetition structure activity diagram

posted by Carlos @ 1:25 AM


do/while Repetition Structure
The do/while repetition structure is similar to the while structure. In thewhile structure, the loop
continuation condition test occurs at the beginning of the loop before the body of the loop
executes. The do/whilestructure tests the loop continuation condition after the loop executes
therefore, the loop body executes at least once. When a do/whileterminates, execution continues
with the statement after the while clause. Note that it is not necessary to use braces in
the do/while structure if there is only one statement in the body. Howeve, most programmers
include the braces to avoid confusion between the while and do/while structures. For example
while ( condition)
Normally is regarded as the header to a while structure. A do/while with no braces around the
single statement body appears as
do
statement
while ( condition );
which can be confusing. The line while (condition); might be misinterpreted by the reader as a

while structure containing an empty statement. Thus, the do/while with one statement is often
written as follows to avoid confusion;
do {
statement
} while (condition);
Example as follows
do/while repetition structure activity diagram

posted by Carlos @ 1:24 AM


CONTROL STRUCTURES QUIZ
Problem Task: Write a program to get the marks obtained from a subject by a student and
calculate the avarage grade for that particular subject?
Here is a piece of pheudocode to help you with your answer
If student's grade is greater than or equal to 90
Print "A"
else
If student's grade is greater than or equal to 80
Print "B"
else
If student's grade is greater than or equal to 70
Print "C"
else
If student's grade is greater than or equal to 60
Print "D"
else
Print "F"

What does this pointer point to ? what are its application?

Every object in C++ has access to its own address through an important pointer
called this pointer. Thethis 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.
Let us try the following example to understand the concept of this pointer:
#include <iostream>
using namespace std;
class Box
{
public:
// Constructor definition
Box(double l=2.0, double b=2.0, double h=2.0)
{
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
}
double Volume()
{
return length * breadth * height;
}
int compare(Box box)
{
return this->Volume() > box.Volume();
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
int main(void)
{
Box Box1(3.3, 1.2, 1.5);
Box Box2(8.5, 6.0, 2.0);

// Declare box1
// Declare box2

if(Box1.compare(Box2))
{
cout << "Box2 is smaller than Box1" <<endl;
}
else

{
cout << "Box2 is equal to or larger than Box1" <<endl;
}
return 0;
}
When the above code is compiled and executed, it produces the following result:
Constructor called.
Constructor called.
Box2 is equal to or larger than Box1

Compare call by reference with call by value?


What is the difference between call by value and call by reference?

Call by Value
Argument is passed by a value
A compiler gets a copy of the variable, and
therefore any modification in sub-function,
won't affect the main function.
When an argument passed by value, the data
item copied to function.
This method is used in common

Call by Reference
Argument is passed by a reference
Here the compiler works on the actual copy
and therefore any modification in subfunction has an impact on the main function.
When an argument passed by reference then
address of that data item passed to the
function
This method is also used when we require
multiple values to be returned by the calling
function

1) Call by Value:-when we call a Function and if a function can accept the Arguments from the
Called Function, Then we must have to Supply some Arguments to the Function. So that the
Arguments those are passed to that function just contains the values from the variables but not an
Actual Address of the variable.

So that generally when we call a Function then we will just pass the variables or the Arguments
and we doesnt Pass the Address of Variables , So that the function will never effects on the
Values or on the variables. So Call by value is just the Concept in which you must have to

Remember that the values those are Passed to the Functions will never effect the Actual Values
those are Stored into the variables.

2) Call By Reference :-When a function is called by the reference then the values those are
passed in the calling functions are affected when they are passed by Reference Means they
change their value when they passed by the References. In the Call by Reference we pass the
Address of the variables whose Arguments are also Send. So that when we use the Reference
then, we pass the Address the Variables.

When we pass the Address of variables to the Arguments then a Function may effect on the
Variables. Means When a Function will Change the Values then the values of Variables gets
Automatically Changed. And When a Function performs Some Operation on the Passed values,
then this will also effect on the Actual Values.

Multiple Inheritances?
Multiple Inheritance in C++
Multiple Inheritance is a feature of C++ where a class can inherit from more than one classes.
The constructors of inherited classes are called in the same order in which they are inherited. For
example, in the following program, Bs constructor is called before As constructor.
#include<iostream>
using namespace std;
class A

{
public:
A() { cout << "A's constructor called" << endl; }
};
class B
{
public:
B() { cout << "B's constructor called" << endl; }
};
class C: public B, public A // Note the order
{
public:
C() { cout << "C's constructor called" << endl; }
};
int main()
{
C c;
return 0;
}
Output:
B's constructor called
A's constructor called
C's constructor called
The destructors are called in reverse order of constructors.
The diamond problem
The diamond problem occurs when two superclasses of a class have a common base class. For
example, in the following diagram, the TA class gets two copies of all attributes of Person class,
this causes ambiguities.

For example, consider the following program.


#include<iostream>
using namespace std;
class Person {
// Data members of person
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
};
class Faculty : public Person {
// data members of Faculty
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};
class Student : public Person {
// data members of Student
public:
Student(int x):Person(x) {
cout<<"Student::Student(int ) called"<< endl;
}
};

class TA : public Faculty, public Student {


public:
TA(int x):Student(x), Faculty(x) {
cout<<"TA::TA(int ) called"<< endl;
}
};
int main() {
TA ta1(30);
}
Person::Person(int ) called
Faculty::Faculty(int ) called
Person::Person(int ) called
Student::Student(int ) called
TA::TA(int ) called
In the above program, constructor of Person is called two times. Destructor of Person will
also be called two times when object ta1 is destructed. So object ta1 has two copies of all
members of Person, this causes ambiguities. The solution to this problem is virtual keyword.
We make the classes Faculty and Student as virtual base classes to avoid two copies of
Person in TA class. For example, consider the following program.
#include<iostream>
using namespace std;
class Person {
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
Person() { cout << "Person::Person() called" << endl; }
};
class Faculty : virtual public Person {
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};
class Student : virtual public Person {
public:
Student(int x):Person(x) {
cout<<"Student::Student(int ) called"<< endl;
}

};
class TA : public Faculty, public Student {
public:
TA(int x):Student(x), Faculty(x) {
cout<<"TA::TA(int ) called"<< endl;
}
};
int main() {
TA ta1(30);
}
Output:
Person::Person() called
Faculty::Faculty(int ) called
Student::Student(int ) called
TA::TA(int ) called
In the above program, constructor of Person is called once. One important thing to note in the
above output is, the default constructor of Person is called. When we use virtual keyword, the
default constructor of grandparent class is called by default even if the parent classes explicitly
call parameterized constructor.
How to call the parameterized constructor of the Person class? The constructor has to be
called in TA class. For example, see the following program.
#include<iostream>
using namespace std;
class Person {
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
Person() { cout << "Person::Person() called" << endl; }
};
class Faculty : virtual public Person {
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};
class Student : virtual public Person {
public:

Student(int x):Person(x) {
cout<<"Student::Student(int ) called"<< endl;
}
};
class TA : public Faculty, public Student {
public:
TA(int x):Student(x), Faculty(x), Person(x) {
cout<<"TA::TA(int ) called"<< endl;
}
};
int main() {
TA ta1(30);
}
Output:
Person::Person(int ) called
Faculty::Faculty(int ) called
Student::Student(int ) called
TA::TA(int ) called
In general, it is not allowed to call the grandparents constructor directly, it has to be called
through parent class. It is allowed only when virtual keyword is used.
As an exercise, predict the output of following programs.
Question 1
#include<iostream>
using namespace std;
class A
{
int x;
public:
void setX(int i) {x = i;}
void print() { cout << x; }
};
class B: public A
{
public:
B() { setX(10); }
};

class C: public A
{
public:
C() { setX(20); }
};
class D: public B, public C {
};
int main()
{
D d;
d.print();
return 0;
}
Question 2
#include<iostream>
using namespace std;
class A
{
int x;
public:
A(int i) { x = i; }
void print() { cout << x; }
};
class B: virtual public A
{
public:
B():A(10) { }
};
class C: virtual public A
{
public:
C():A(10) { }
};

class D: public B, public C {


};
int main()
{
D d;
d.print();
return 0;
}
What is a friend function? What are its merits and demerits of using a friend function?
A friend function of a class is defined outside that class' scope but it has the right to access all
private and protected members of the class. Even though the prototypes for friend functions
appear in the class definition, friends are not member functions.
A friend can be a function, function template, or member function, or a class or class template, in
which case the entire class and all of its members are friends.
To declare a function as a friend of a class, precede the function prototype in the class definition
with keyword friend as follows:
class Box
{
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};
To declare all member functions of class ClassTwo as friends of class ClassOne, place a
following declaration in the definition of class ClassOne:
friend class ClassTwo;
Consider the following program:
#include <iostream>
using namespace std;
class Box
{
double width;
public:

friend void printWidth( Box box );


void setWidth( double wid );
};
// Member function definition
void Box::setWidth( double wid )
{
width = wid;
}
// Note: printWidth() is not a member function of any class.
void printWidth( Box box )
{
/* Because printWidth() is a friend of Box, it can
directly access any member of this class */
cout << "Width of box : " << box.width <<endl;
}
// Main function for the program
int main( )
{
Box box;
// set box width without member function
box.setWidth(10.0);
// Use friend function to print the wdith.
printWidth( box );
return 0;
}
When the above code is compiled and executed, it produces the following result:
Width of box : 10
What are some advantages/disadvantages of using friend functions?
They provide a degree of freedom in the interface design options.
Member functions and friend functions are equally privileged (100% vested). The major
difference is that a friend function is called like f(x), while a member function is called like x.f().
Thus the ability to choose between member functions (x.f()) and friend functions (f(x)) allows a
designer to select the syntax that is deemed most readable, which lowers maintenance costs.

The major disadvantage of friend functions is that they require an extra line of code when you
want dynamic binding. To get the effect of a virtual friend, the friend function should call a
hidden (usually protected) virtual member function. This is called the Virtual Friend Function
Idiom. For example:
class Base {
public:
friend void f(Base& b);
...
protected:
virtual void do_f();
...
};
inline void f(Base& b)
{
b.do_f();
}
class Derived : public Base {
public:
...
protected:
virtual void do_f(); // "Override" the behavior of f(Base& b)
...
};
void userCode(Base& b)
{
f(b);
}
The statement f(b) in userCode(Base&) will invoke b.do_f(), which is virtual. This means
that Derived::do_f() will get control if b is actually a object of class Derived. Note
that Derivedoverrides the behavior of the protected virtual member function do_f(); it
does not have its own variation of the friend function, f(Base&).

Difference between function prototyping and function overloading?

In C++ all functions must be declared before they are used. This is accomplished using function
prototype. Prototypes enable complier to provide stronger type checking. When prototype is
used, the compiler can find and report any illegal type conversions between the type of
arguments used to call a function and the type definition of its parameters. It can also find the
difference between the no of arguments used to call a function and the number of parameters in

the function. Thus function prototypes help us trap bugs before they occur. In addition, they help
verify that your program is working correctly by not allowing functions to be called with
mismatched arguments.
A general function prototype looks like following:
return_type func_name(type param_name1, type param_name2, ,type param_nameN);
The type indicates data type. parameter names are optional in prototype.
Following program illustrates the value of function parameters:
void sqr_it(int *i);
int main()
{
int num;
num = 10;
sqr_it(num);
return 0;
}

//prototype of function sqr_it

//type mismatch

void sqr_it(int *i)


{
*i = *i * *i;
}
Since sqr_it() has pointer to integer as its parameter, the program throws an error when we pass
an integer to it.

C++ function overloading programs


Function overloading in C++: C++ program for function overloading. Function overloading
means two or more functions can have the same name but either the number of arguments or the
data type of arguments has to be different. Return type has no role because function will return a
value when it is called and at compile time compiler will not be able to determine which function
to call. In the first example in our code we make two functions one for adding two integers and
other for adding two floats but they have same name and in the second program we make two
functions with identical names but pass them different number of arguments. Function
overloading is also known as compile time polymorphism.
C++ programming code
#include <iostream>
using namespace std;
/* Function arguments are of different data type */

long add(long, long);


float add(float, float);
int main()
{
long a, b, x;
float c, d, y;
cout << "Enter two integers\n";
cin >> a >> b;
x = add(a, b);
cout << "Sum of integers: " << x << endl;
cout << "Enter two floating point numbers\n";
cin >> c >> d;
y = add(c, d);
cout << "Sum of floats: " << y << endl;
return 0;
}
long add(long x, long y)
{
long sum;
sum = x + y;
return sum;
}
float add(float x, float y)
{
float sum;
sum = x + y;
return sum;
}
In the above program, we have created two functions "add" for two different data types you can
create more than two functions with same name according to requirement but making sure that
compiler will be able to determine which one to call. For example you can create add function
for integers, doubles and other data types in above program. In these functions you can see the

code of functions is same except data type, C++ provides a solution to this problem we can
create a single function for different data types which reduces code size which is via templates.
C++ programming code for function overloading
#include <iostream>
using namespace std;
/* Number of arguments are different */
void display(char []); // print the string passed as argument
void display(char [], char []);
int main()
{
char first[] = "C programming";
char second[] = "C++ programming";
display(first);
display(first, second);
return 0;
}
void display(char s[])
{
cout << s << endl;
}
void display(char s[], char t[])
{
cout << s << endl << t << endl;
}
Output of program:
C programming
C programming
C++ programming

What is the difference between opening a file with constructor function & opening a file with
open () function? When is one method preferred over other?

Opening a file using constructor


This involves two steps
1. Create file stream subject to manage the stream using the appropriate class. That is the class
ofstream is used to create the output stream and the class ifstream to create the input stream.
2. Initialize the file object with the desired filename.
Syntax:
Ofstream object(file_name);
Example:
Ofstream obj(sample.doc)
This creates obj1 as an ofstream that manages the output stream.
#include stream.h
#include string.h
Void main()
{
char str[]=ssi computer center;
ofstream outfile(sample.doc);
for(int j=0;j<>Syntax:
Ifstream object (file_name);
Example:
Ifstream obj(sample.doc)
This creates obj1 as an ifstream that manages the input stream.
#include fstream.h
void main()
{
char ch;
ifstream in(sample.txt);
while(!in.eof())
{
in.get(ch);
cout<< ch; } }
#include fstream.h
void main()
{

const int MAX=80;


char buffer[MAX];
ifstream infile(sample.txt);
while(!infile.eof())
{
infile.getline(buffer, MAX);
cout<< buffer;
}
}

To show: How to use the write(), seekp(), tellp(), open() and close() member functions in
C++ programming
// using the seekp() and tellp() member functions
#include <iostream>
#include <fstream>
using namespace std;
void main(void)
{
// provide a full path if needed
char filename[ ] = "C:\\testfileio4.txt";
ofstream outputfile;
int locate;
// creating, opening and writing data to a file
outputfile.open(filename, ios::out);
// simple error handling for file creating/opening test if fail to open
if(outputfile.fail())
{
cout<<"Creating and opening "<<filename<<" file for writing\n";
cout<<"----------------------------------------------------\n";
cout<<"The "<<filename<<" file could not be created/opened!\n";
cout<<"Possible errors:\n";
cout<<"1. The file does not exist.\n";
cout<<"2. The path was not found.\n";
exit(1); // just exit
// 0-normal, non zero - some error

}
// if successful creating/opening the file
else
{
cout<<"The "<<filename<<" file was created and opened successfully!\n";
cout<<"\nDo some file writing....\n\n";
outputfile.write("Testing: Just simple example.", 29);
// tell the pointer position
locate = outputfile.tellp();
// seek the pointer position with offset
outputfile.seekp(locate-16);
// write for 7 length
outputfile.write(" rumble", 7);
// close the output file
outputfile.close();
// simple error handling for output files closing test if fail to close the file, do...
if(outputfile.fail())
{
cout<<"The "<<filename<<" file could not be closed!\n";
exit(1);
}
// if successful to close the file
else
cout<<"\nThe "<<filename<<" file was closed successfully!\n";
}
}
Output example:
The C:\testfileio4.txt file was created and opened successfully!
Do some file writing....
The C:\testfileio4.txt file was closed successfully!
Press any key to continue . . .
The testfileio4.txt file content is shown below.

Standard Template Library


STL The C++ STL (Standard Template Library) is a powerful set of C++ template classes to
provide general-purpose templatized classes and functions that implement many popular and
commonly used algorithms and data structures like vectors, lists, queues, and stacks. The STL
is a set of abstract data-types, functions, and algorithms designed to handle user-specified datatypes The Standard Template Library is the idea of generic programming o The implementation
of algorithms or data structures without being dependent on the type of data being handled
Subject Teacher: Shubhashree Savant Page 23 The STL is a generic library, meaning that its
components are heavily parameterized: o almost every component in the STL is a template STL
is divided into three parts namely containers, algorithms, and iterators o All these three parts can
be used for different programming problems At the core of the C++ Standard Template Library
are following three wellstructured components: Component Description Containers 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 Algorithms act on containers. They
provide the means by which you will perform initialization, sorting, searching, and transforming
of the contents of containers. Iterators Iterators are used to step through the elements of
collections of objects. These collections may be containers or subsets of containers.

Hope you already understand the concept of C++ Template which we already have discussed in
one of the chapters. The C++ STL (Standard Template Library) is a powerful set of C++
template classes to provides general-purpose templatized classes and functions that implement
many popular and commonly used algorithms and data structures like vectors, lists, queues, and
stacks.
At the core of the C++ Standard Template Library are following three well-structured
components:
Component

Description

Containers

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

Algorithms act on containers. They provide the means by


which you will perform initialization, sorting, searching,
and transforming of the contents of containers.

Iterators

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

Function Template

Templates are the foundation of generic programming, which involves writing code in a way that
is independent of any particular type.
A template is a blueprint or formula for creating a generic class or a function. The library
containers like iterators and algorithms are examples of generic programming and have been
developed using template concept.
There is a single definition of each container, such as vector, but we can define many different
kinds of vectors for example, vector <int> or vector <string>.
You can use templates to define functions as well as classes, let us see how do they work:
Function Template:
The general form of a template function definition is shown here:
template <class type> ret-type func-name(parameter list)

{
// body of function
}
Here, type is a placeholder name for a data type used by the function. This name can be used
within the function definition.
The following is the example of a function template that returns the maximum of two values:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b)
{
return a < b ? b:a;
}
int main ()
{
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
If we compile and run above code, this would produce the following result:
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World
Class Template:

Just as we can define function templates, we can also define class templates. The general form of
a generic class declaration is shown here:
template <class type> class class-name {
.
.
.
}
Here, type is the placeholder type name, which will be specified when a class is instantiated.
You can define more than one generic data type by using a comma-separated list.
Following is the example to define class Stack<> and implement generic methods to push and
pop the elements from the stack:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Stack {
private:
vector<T> elems;

// elements

public:
void push(T const&); // push element
void pop();
// pop element
T top() const;
// return top element
bool empty() const{
// return true if empty.
return elems.empty();
}
};
template <class T>
void Stack<T>::push (T const& elem)
{
// append copy of passed element
elems.push_back(elem);
}
template <class T>
void Stack<T>::pop ()
{

if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// remove last element
elems.pop_back();
}
template <class T>
T Stack<T>::top () const
{
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// return copy of last element
return elems.back();
}
int main()
{
try {
Stack<int>
intStack; // stack of ints
Stack<string> stringStack; // stack of strings
// manipulate int stack
intStack.push(7);
cout << intStack.top() <<endl;
// manipulate string stack
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
If we compile and run above code, this would produce the following result:
7
hello
Exception: Stack<>::pop(): empty stack
File Pointers and fopen

[This section corresponds to K&R Sec. 7.5]


How will we specify that we want to access a particular data file? It would theoretically be
possible to mention the name of a file each time it was desired to read from or write to it. But
such an approach would have a number of drawbacks. Instead, the usual approach (and the one
taken in C's stdio library) is that you mention the name of the file once, at the time you open it.
Thereafter, you use some little token--in this case, the file pointer--which keeps track (both for
your sake and the library's) of which file you're talking about. Whenever you want to read from
or write to one of the files you're working with, you identify that file by using its file pointer
(that is, the file pointer you obtained when you opened the file). As we'll see, you store file
pointers in variables just as you store any other data you manipulate, so it is possible to have
several files open, as long as you use distinct variables to store the file pointers.
You declare a variable to store a file pointer like this:
FILE *fp;
The type FILE is predefined for you by <stdio.h>. It is a data structure which holds the
information the standard I/O library needs to keep track of the file for you. For historical reasons,
you declare a variable which is a pointer to this FILE type. The name of the variable can (as for
any variable) be anything you choose; it is traditional to use the letters fp in the variable name
(since we're talking about a file pointer). If you were reading from two files at once you'd
probably use two file pointers:
FILE *fp1, *fp2;
If you were reading from one file and writing to another you might declare and input file pointer
and an output file pointer:
FILE *ifp, *ofp;
Like any pointer variable, a file pointer isn't any good until it's initialized to point to something.
(Actually, no variable of any type is much good until you've initialized it.) To actually open a
file, and receive the ``token'' which you'll store in your file pointer variable, you
call fopen. fopen accepts a file name (as a string) and a mode value indicating among other
things whether you intend to read or write this file. (The mode variable is also a string.) To open
the file input.dat for reading you might call
ifp = fopen("input.dat", "r");
The mode string "r" indicates reading. Mode "w" indicates writing, so we could
open output.dat for output like this:
ofp = fopen("output.dat", "w");
The other values for the mode string are less frequently used. The third major mode is "a" for
append. (If you use "w" to write to a file which already exists, its old contents will be discarded.)
You may also add a +character to the mode string to indicate that you want to both read and
write, or a b character to indicate that you want to do ``binary'' (as opposed to text) I/O.
One thing to beware of when opening files is that it's an operation which may fail. The requested
file might not exist, or it might be protected against reading or writing. (These possibilities ought
to be obvious, but it's easy to forget them.) fopen returns a null pointer if it can't open the

requested file, and it's important to check for this case before going off and using fopen's return
value as a file pointer. Every call to fopen will typically be followed with a test, like this:
ifp = fopen("input.dat", "r");
if(ifp == NULL)
{
printf("can't open file\n");
exit or return
}
If fopen returns a null pointer, and you store it in your file pointer variable and go off and try to
do I/O with it, your program will typically crash.
It's common to collapse the call to fopen and the assignment in with the test:
if((ifp = fopen("input.dat", "r")) == NULL)
{
printf("can't open file\n");
exit or return
}
You don't have to write these ``collapsed'' tests if you're not comfortable with them, but you'll
see them in other people's code, so you should be able to read them

Differnce between multiple and multilevel inheriatnace?


Multilevel Inheritance

When a class is derived form another derived class is called multilevel inheritance. In the
following figure the class A serves as a base class for the derived class B, which in turn serves as
a base class for the derived class C/ the class B is known as intermediate base class since it
provides a link for the inheritance between A and C. the chain ABC is known as inheritance
path.
class A{};
class B: public A{};
class C: public B{};

//Base Class
// B derived from A
// C derived from B

Example:
#include<iostream.h>
#include<conio.h>
class Student //Base Class
{
protected:
int rno;
public:
void get_number(int);
void put_number(void);
};
void Student::get_number(int a)
{ rno = a; }
void Student::put_number(void)
{
cout<<"Roll Number :"<<rno<<endl;
}
class Test: public Student //Intermediate Base Class
{
protected:
int sub1;
int sub2;
public:
void get_marks(int , int );

void put_marks(void);
};
void Test::get_marks(int x, int y)
{
sub1 = x;
sub2 = y;
}
void Test::put_marks(void)
{
cout<<"Subject-1 : "<<sub1<<endl;
cout<<"Subject-2 :"<<sub2<<endl;
}
class Result: public Test //Derived Class
{
int total;
public:
void display(void);
};
void Result::display(void)
{
total = sub1 + sub2;
put_number();
put_marks();
cout<<"Total : "<<total<<endl;
}
void main()
{
clrscr();
Result stud;
stud.get_number(111);
stud.get_marks(56,78);
stud.display();
getch();
}

Multiple Inheritance in C++


Multiple Inheritance is a feature of C++ where a class can inherit from more than one classes.
The constructors of inherited classes are called in the same order in which they are inherited. For
example, in the following program, Bs constructor is called before As constructor.
#include<iostream>
using namespace std;
class A
{
public:
A() { cout << "A's constructor called" << endl; }
};
class B
{
public:
B() { cout << "B's constructor called" << endl; }
};
class C: public B, public A // Note the order
{
public:
C() { cout << "C's constructor called" << endl; }
};
int main()
{
C c;
return 0;
}
Output:
B's constructor called
A's constructor called
C's constructor called
The destructors are called in reverse order of constructors.
The diamond problem
The diamond problem occurs when two superclasses of a class have a common base class. For

example, in the following diagram, the TA class gets two copies of all attributes of Person class,
this causes ambiguities.

For example, consider the following program.


#include<iostream>
using namespace std;
class Person {
// Data members of person
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
};
class Faculty : public Person {
// data members of Faculty
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};
class Student : public Person {
// data members of Student
public:
Student(int x):Person(x) {
cout<<"Student::Student(int ) called"<< endl;
}

};
class TA : public Faculty, public Student {
public:
TA(int x):Student(x), Faculty(x) {
cout<<"TA::TA(int ) called"<< endl;
}
};
int main() {
TA ta1(30);
}
Person::Person(int ) called
Faculty::Faculty(int ) called
Person::Person(int ) called
Student::Student(int ) called
TA::TA(int ) called
In the above program, constructor of Person is called two times. Destructor of Person will
also be called two times when object ta1 is destructed. So object ta1 has two copies of all
members of Person, this causes ambiguities. The solution to this problem is virtual keyword.
We make the classes Faculty and Student as virtual base classes to avoid two copies of
Person in TA class. For example, consider the following program.
#include<iostream>
using namespace std;
class Person {
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
Person() { cout << "Person::Person() called" << endl; }
};
class Faculty : virtual public Person {
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};
class Student : virtual public Person {
public:

Student(int x):Person(x) {
cout<<"Student::Student(int ) called"<< endl;
}
};
class TA : public Faculty, public Student {
public:
TA(int x):Student(x), Faculty(x) {
cout<<"TA::TA(int ) called"<< endl;
}
};
int main() {
TA ta1(30);
}
Output:
Person::Person() called
Faculty::Faculty(int ) called
Student::Student(int ) called
TA::TA(int ) called
In the above program, constructor of Person is called once. One important thing to note in the
above output is, the default constructor of Person is called. When we use virtual keyword, the
default constructor of grandparent class is called by default even if the parent classes explicitly
call parameterized constructor.
How to call the parameterized constructor of the Person class? The constructor has to be
called in TA class. For example, see the following program.
#include<iostream>
using namespace std;
class Person {
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
Person() { cout << "Person::Person() called" << endl; }
};
class Faculty : virtual public Person {
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}

};
class Student : virtual public Person {
public:
Student(int x):Person(x) {
cout<<"Student::Student(int ) called"<< endl;
}
};
class TA : public Faculty, public Student {
public:
TA(int x):Student(x), Faculty(x), Person(x) {
cout<<"TA::TA(int ) called"<< endl;
}
};
int main() {
TA ta1(30);
}
Output:
Person::Person(int ) called
Faculty::Faculty(int ) called
Student::Student(int ) called
TA::TA(int ) called
In general, it is not allowed to call the grandparents constructor directly, it has to be called
through parent class. It is allowed only when virtual keyword is used.

Ambiguous function calls in multiple inheritance


A subclass can be derived from more than one superclass. This is multiple inheritance.
class A
{
public:
void show(){cout<<"A";}
};
class B
{
public:
void show() { cout<<"B"; }

};
/* class C is multiple derived from its superclass A and B */
class C:public A, public B
{
};
int main()
{
C c;
c.show();
}
Ambiguous call:
For the above sample program, c.show() is ambiguous to get resolved among candidate
functionsB::show() and A::show()
Solution to ambiguous calls in multiple inheritance:
Use scope resolution operator to explicitly specify which base class's member function is to be
invoked.
Like, c.A::show();

What is a copy constructor & when it is invocked? Wap with a class Abc and one integer
data type member?overload the copy constructor and assignment operator for the class?
A copy constructor is a member function which initializes an object using another object of the
same class. A copy constructor has the following general function prototype:
ClassName (const ClassName &old_obj);
Following is a simple example of copy constructor.
#include<iostream>
using namespace std;
class Point
{
private:
int x, y;
public:
Point(int x1, int y1) { x = x1; y = y1; }

// Copy constructor
Point(const Point &p2) {x = p2.x; y = p2.y; }
int getX()
int getY()

{ return x; }
{ return y; }

};
int main()
{
Point p1(10, 15); // Normal constructor is called here
Point p2 = p1; // Copy constructor is called here
// Let us access values assigned by constructors
cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();
return 0;
}
Output:
p1.x = 10, p1.y = 15
p2.x = 10, p2.y = 15

When is copy constructor called?


In C++, a Copy Constructor may be called in following cases:
1. When an object of the class is returned by value.
2. When an object of the class is passed (to a function) by value as an argument.
3. When an object is constructed based on another object of the same class.
4. When compiler generates a temporary object.
It is however, not guaranteed that a copy constructor will be called in all these cases, because the
C++ Standard allows the compiler to optimize the copy away in certain cases, one example being
the return value optimization (sometimes referred to as RVO).
Source: http://www.geeksforgeeks.org/g-fact-13/

When is user defined copy constructor needed?


If we dont define our own copy constructor, the C++ compiler creates a default copy constructor
for each class which does a member wise copy between objects. The compiler created copy
constructor works fine in general. We need to define our own copy constructor only if an object
has pointers or any run time allocation of resource like file handle, a network connection..etc.

Copy constructor vs Assignment Operator


Which of the following two statements call copy constructor and which one calls assignment
operator?
MyClass t1, t2;
MyClass t3 = t1; // ----> (1)
t2 = t1;
// -----> (2)
Copy constructor is called when a new object is created from an existing object, as a copy of the
existing object. Assignment operator is called when an already initialized object is assigned a
new value from another existing object. In the above example (1) calls copy constrictor and (2)
calls assignment operator. See this for more details.

Although using the assignment operator is fairly straightforward, correctly implementing an


overloaded assignment operator can be a little more tricky than you might anticipate. There are
two primary reasons for this. First, there are some cases where the assignment operator isnt
called when you might expect it to be. Second, there are some issues in dealing with dynamically
allocated memory (which we will cover in the next lesson).
The assignment operator is used to copy the values from one object to another already existing
object. The key words here are already existing. Consider the following example:
1

Cents cMark(5); // calls Cents constructor

Cents cNancy; // calls Cents default constructor

cNancy = cMark; // calls Cents assignment operator

In this case, cNancy has already been created by the time the assignment is executed.
Consequently, the Cents assignment operator is called. The assignment operator must be
overloaded as a member function.
What happens if the object being copied into does not already exist? To understand what
happens in that case, we need to talk about the copy constructor.
The copy constructor
Consider the following example:
1

Cents cMark(5); // calls Cents constructor

Cents cNancy = cMark; // calls Cents copy constructor!

Because the second statement uses an equals symbol in it, you might expect that it calls the
assignment operator. However, it doesnt! It actually calls a special type of constructor called a
copy constructor. A copy constructor is a special constructor that initializes a new object from
an existing object.
The purpose of the copy constructor and the assignment operator are almost equivalent both
copy one object to another. However, the assignment operator copies to existing objects, and the
copy constructor copies to newly created objects.
The difference between the copy constructor and the assignment operator causes a lot of
confusion for new programmers, but its really not all that difficult. Summarizing:
If a new object has to be created before the copying can occur, the copy constructor is
used.
If a new object does not have to be created before the copying can occur, the assignment
operator is used.

There are three general cases where the copy constructor is called instead of the assignment
operator:
1. When instantiating one object and initializing it with values from another object (as in the
example above).
2. When passing an object by value.
3. When an object is returned from a function by value.
In each of these cases, a new variable needs to be created before the values can be copied
hence the use of the copy constructor.
Because the copy constructor and assignment operator essentially do the same job (they are just
called in different cases), the code needed to implement them is almost identical.
An overloaded assignment operator and copy constructor example
Now that you understand the difference between the copy constructor and assignment operator,
lets see how they are implemented. For simple classes such as our Cents class, it is very
straightforward.
Here is a simplified version of our Cents class:
1

class Cents

private:

4
5

int m_nCents;
public:

Cents(int nCents=0)

m_nCents = nCents;

9
10

}
};

First, lets add the copy constructor. Thinking about this logically, because it is a constructor, it
needs to be named Cents. Because it needs to copy an existing object, it needs to take a Cents
object as a parameter. And finally, because it is a constructor, it doesnt have a return type.
Putting all of these things together, here is our Cents class with a copy constructor.
1

class Cents

private:

4
5

int m_nCents;
public:

Cents(int nCents=0)

m_nCents = nCents;

10
11

// Copy constructor

12

Cents(const Cents &cSource)

13

14

m_nCents = cSource.m_nCents;

15
16

}
};

A copy constructor looks just like a normal constructor that takes a parameter of the class type.
However, there are two things which are worth explicitly mentioning. First, because our copy
constructor is a member of Cents, and our parameter is a Cents, we can directly access the
internal private data of our parameter. Second, the parameter MUST be passed by reference, and
not by value. Can you figure out why?

The answer lies above in the list that shows the cases where a copy constructor is called. A copy
constructor is called when a parameter is passed by value. If we pass our cSource parameter by
value, it would need to call the copy constructor to do so. But calling the copy constructor again
would mean the parameter is passed by value again, requiring another call to the copy
constructor. This would result in an infinite recursion (well, until the stack memory ran out and
the the program crashed). Fortunately, modern C++ compilers will produce an error if you try to
do this:
C:\\Test.cpp(431) : error C2652: 'Cents' : illegal copy constructor: first parameter must not be a
'Cents'
The first parameter in this case must be a reference to a Cents!
Now lets overload the assignment operator. Following the same logic, the prototype and
implementation are fairly straightforward:
1

class Cents

private:

4
5

int m_nCents;
public:

Cents(int nCents=0)

m_nCents = nCents;

10
11

// Copy constructor

12

Cents(const Cents &cSource)

13

14

m_nCents = cSource.m_nCents;

15

16
17

Cents& operator= (const Cents &cSource);

18
19

};

20
21

Cents& Cents::operator= (const Cents &cSource)

22

23

// do the copy

24

m_nCents = cSource.m_nCents;

25
26

// return the existing object

27

return *this;

28

A couple of things to note here: First, the line that does the copying is exactly identical to the one
in the copy constructor. This is typical. In order to reduce duplicate code, the portion of the code
that does the actual copying could be moved to a private member function that the copy
constructor and overloaded assignment operator both call. Second, were returning *this so we
can chain multiple assigments together:
1

cMark = cNancy = cFred = cJoe; // assign cJoe to everyone

If you need a refresher on chaining, we cover that in the section on overloading the I/O
operators.
Finally, note that it is possible in C++ to do a self-assignment:
1

cMark = cMark; // valid assignment

In these cases, the assignment operator doesnt need to do anything (and if the class uses
dynamic memory, it can be dangerous if it does). It is a good idea to do a check for selfassignment at the top of an overloaded assignment operator. Here is an example of how to do
that:
1

Cents& Cents::operator= (const Cents &cSource)

// check for self-assignment by comparing the address of the

// implicit object and the parameter

if (this == &cSource)

return *this;

7
8

// do the copy

m_nCents = cSource.m_nCents;

10
11

// return the existing object

12

return *this;

13

Note that there is no need to check for self-assignment in a copy-constructor. This is because the
copy constructor is only called when new objects are being constructed, and there is no way to
assign a newly created object to itself in a way that calls to copy constructor.
Default memberwise copying
Just like other constructors, C++ will provide a default copy constructor if you do not provide
one yourself. However, unlike other operators, C++ will provide a default assignment
operator if you do not provide one yourself!
Because C++ does not know much about your class, the default copy constructor and default
assignment operators it provides are very simple. They use a copying method known as a
memberwise copy (also known as a shallow copy). We will talk more about shallow and deep
copying in the next lesson.

What are the c-type strings?How are they different from the string defined by the standard c++
string class?
C++ provides following two types of string representations:

The C-style character string.

The string class type introduced with Standard C++.


The C-Style Character String:
The C-style character string originated within the C language and continues to be supported
within C++. This string is actually a one-dimensional array of characters which is terminated by
a nullcharacter '\0'. Thus a null-terminated string contains the characters that comprise the string
followed by a null.

The following declaration and initialization create a string consisting of the word "Hello". To
hold the null character at the end of the array, the size of the character array containing the string
is one more than the number of characters in the word "Hello."
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
If you follow the rule of array initialization, then you can write the above statement as follows:
char greeting[] = "Hello";
Following is the memory presentation of above defined string in C/C++:

Actually, you do not place the null character at the end of a string constant. The C++ compiler
automatically places the '\0' at the end of the string when it initializes the array. Let us try to print
above-mentioned string:
#include <iostream>
using namespace std;
int main ()
{
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
cout << "Greeting message: ";
cout << greeting << endl;
return 0;
}
When the above code is compiled and executed, it produces result something as follows:
Greeting message: Hello
C++ supports a wide range of functions that manipulate null-terminated strings:

S.N. Function & Purpose


1

strcpy(s1, s2);
Copies string s2 into string s1.

strcat(s1, s2);
Concatenates string s2 onto the end of string s1.

strlen(s1);
Returns the length of string s1.

strcmp(s1, s2);
Returns 0 if s1 and s2 are the same; less than 0 if s1<s2; greater than 0 if s1>s2.

strchr(s1, ch);
Returns a pointer to the first occurrence of character ch in string s1.

strstr(s1, s2);
Returns a pointer to the first occurrence of string s2 in string s1.

Following example makes use of few of the above-mentioned functions:


#include <iostream>
#include <cstring>
using namespace std;
int main ()
{
char str1[10] = "Hello";
char str2[10] = "World";
char str3[10];
int len ;
// copy str1 into str3
strcpy( str3, str1);
cout << "strcpy( str3, str1) : " << str3 << endl;
// concatenates str1 and str2
strcat( str1, str2);
cout << "strcat( str1, str2): " << str1 << endl;
// total lenghth of str1 after concatenation
len = strlen(str1);
cout << "strlen(str1) : " << len << endl;
return 0;
}

When the above code is compiled and executed, it produces result something as follows:
strcpy( str3, str1) : Hello
strcat( str1, str2): HelloWorld
strlen(str1) : 10
The String Class in C++:
The standard C++ library provides a string class type that supports all the operations mentioned
above, additionally much more functionality. We will study this class in C++ Standard Library
but for now let us check following example:
At this point, you may not understand this example because so far we have not discussed Classes
and Objects. So can have a look and proceed until you have understanding on Object Oriented
Concepts.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str1 = "Hello";
string str2 = "World";
string str3;
int len ;
// copy str1 into str3
str3 = str1;
cout << "str3 : " << str3 << endl;
// concatenates str1 and str2
str3 = str1 + str2;
cout << "str1 + str2 : " << str3 << endl;
// total lenghth of str3 after concatenation
len = str3.size();
cout << "str3.size() : " << len << endl;
return 0;
}
When the above code is compiled and executed, it produces result something as follows:
str3 : Hello
str1 + str2 : HelloWorld

str3.size() : 10

--notes
This page summarizes many of the things you may find it useful to know when working with
either C-strings or objects of the C++ string class.
The term string generally means an ordered sequence of characters, with a first character, a
second character, and so on, and in most programming languages such strings are enclosed in
either single or double quotes. In C++ the enclosing delimiters are double quotes. In this form
the string is referred to as a string literal and we often use such string literals in output
statements when we wish to display text on the screen for the benefit of our users. For example,
the usual first C++ program displays the string literal "Hello, world!" on the screen with the
following output statement:
cout << "Hello, world!" << endl;
However, without string variables about all we can do with strings is output string literals to the
screen, so we need to expand our ability to handle string data. When we talk about strings in
C++, we must be careful because the C language, with which C++ is meant to be backward
compatible, had one way of dealing with strings, while C++ has another, and to further
complicate matters there are many non-standard implementations of C++ strings. These should
gradually disappear as compiler vendors update their products to implement the string
component of the C++ Standard Library.
As a programmer, then, you must distinguish between the following three things:
1. An "ordinary" array of characters, which is just like any other array and has no special
properties that other arrays do not have.
2. A C-string, which consists of an array of characters terminated by the null character '\0',
and which therefore is different from an ordinary array of characters. There is a whole
library of functions for dealing with strings represented in this form. Its header file
is <cstring>. In some implementations this library may be automatically included when
you include other libraries such as the <iostream> library. Note that the null character
may very well not be the very last character in the C-string array, but it will be the first
character beyond the last character of the actual string data in in that array. For example
if you have a C-string storing "Hello" in a character array of size 10, then the letters of
the word "Hello" will be in positions with indices 0 to 4, there will be a null character at
index 5, and the locations with indices 6 to 9 will contain who-knows-what. In any case,
it's the null character at index 5 that makes this otherwise ordinary character array a Cstring.
3. A C++ string object, which is an instance of a "class" data type whose actual internal
representation you need not know or care about, as long as you know what you can and
can't do with variables (and constants) having this data type. There is a library of C++
string functions as well, available by including the <string> header file.

Both the C-string library functions and the C++ string library functions are available to C++
programs. But, don't forget that these are two *different* function libraries, and the functions of
the first library have a different notion of what a string is from the corresponding notion held by
the functions of the second library. There are two further complicating aspects to this situation:
first, though a function from one of the libraries may have a counterpart in the other library (i.e.,
a function in the other library designed to perform the same operation), the functions may not be
used in the same way, and may not even have the same name; second, because of backward
compatibility many functions from the C++ string library can be expected to work fine and do
the expected thing with C-style strings, but not the other way around.
The last statement above might seem to suggest we should use C++ strings and forget about Cstrings altogether, and it is certainly true that there is a wider variety of more intuitive operations
available for C++ strings. However, C-strings are more primitive, you may therefore find them
simpler to deal with (provided you remember a few simple rules, such as the fact that the null
character must always terminate such strings), and certainly if you read other, older programs
you will see lots of C-strings. So, use whichever you find more convenient, but if you choose
C++ strings and occasionally need to mix the two for some reason, be extra careful. Finally,
there are certain situations in which C-strings must be used.
To understand strings, you will have to spend some time studying sample programs. This study
must include the usual prediction of how you expect a program to behave for given input,
followed by a compile, link and run to test your prediction, as well as subsequent modification
and testing to investigate questions that will arise along the way. In addition to experimenting
with any supplied sample programs, you should be prepared to make up your own.
In the following examples we attempt to draw the distinction between the two string
representations and their associated operations. The list is not complete, but we do indicate how
to perform many of the more useful kinds of tasks with each kind of string. The left-hand column
contains examples relevant to C-strings and the right-hand column shows analogous examples in
the context of C++ strings.
C-strings (#include <cstring>)
C++ strings (#include <string>)
===============================
================================
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Declaring a C-string variable
Declaring a C++ string object
--------------------------------------------------------char str[10];
string str;
Initializing a C-string variable
Initializing a C++ string object
--------------------------------------------------------------char str1[11] = "Call home!";
string str1("Call home!");
char str2[] = "Send money!";
string str2 = "Send money!";
char str3[] = {'O', 'K', '\0'};
string str3("OK");
Last line above has same effect as:
char str3[] = "OK";

string str4(10, 'x');


Assigning to a C-string variable
Assigning to a C++ string object
--------------------------------------------------------------Can't do it, i.e., can't do this:
string str;
char str[10];
str = "Hello";
str = "Hello!";
str = otherString;
Concatenating two C-strings
Concatenating two C++ string objects
-------------------------------------------------------------strcat(str1, str2);
str1 += str2;
strcpy(str, strcat(str1, str2));
str = str1 + str2;
Copying a C-string variable
Copying a C++ string object
----------------------------------------------------char str[20];
string str;
strcpy(str, "Hello!");
str = "Hello";
strcpy(str, otherString);
str = otherString;
Accessing a single character
Accessing a single character
------------------------------------------------------str[index]
str[index]
str.at(index)
str(index, count)
Comparing two C-strings
Comparing two C++ string objects
-----------------------------------------------------if (strcmp(str1, str2) < 0)
if (str1 < str2)
cout << "str1 comes 1st.";
cout << "str1 comes 1st.";
if (strcmp(str1, str2) == 0)
if (str1 == str2)
cout << "Equal strings.";
cout << "Equal strings.";
if (strcmp(str1, str2) > 0)
if (str1 > str2)
cout << "str2 comes 1st.";
cout << "str2 comes 1st.";
Finding the length of a C-string
Finding the length of a C++ string object
-----------------------------------------------------------------------strlen(str)
str.length()
Output of a C-string variable
Output of a C++ string object
--------------------------------------------------------cout << str;
cout << str;
cout << setw(width) << str;
cout << setw(width) << str;
In what follows, keep in mind that cin ignores white space when reading a string,
while cin.get(), cin.getline() and getline() do not. Remember too
that cin.getline() and getline() consume the delimiter while cin.get() does not. Finally, cin can be

replaced with any open input stream, since file input with inFile, say, behaves in a manner
completely analogous to the corresponding behavior of cin. Analogously, in the output examples
given immediately above, cout could be replaced with any text output stream variable,
say outFile. In all cases, numCh is the maximum number of characters that will be read.
Input of a C-style string variable
Input of a C++ string object
------------------------------------------------------------cin >> s;
cin >> s;
cin.get(s, numCh+1);
cin.get(s, numCh+1,'\n');
cin.get(s, numCh+1,'x');
cin.getline(s, numCh+1);
getline(cin, s);
cin.getline(s, numCh+1, '\n');
cin.getline(s, numCh+1, 'x');
getline(cin, s, 'x');
A useful naming convention for C-strings is illustrated by examples like
typedef char String80[81];
typedef char String20[21];
in which the two numbers in each definition differ by 1 to allow for the null character '\0' to be
stored in the array of characters, but to *not* be considered as part of the string stored there. No
analog to this naming convention is necessary for C++ strings, since for all practical purposes,
each C++ string variable may contain a string value of virtually unlimited length.

What is a virtual function? How a virtual function is different from pure virtual function?
What is Virtual Functions in C++?
Explanation
Virtual Function is a function that is declared within a base class and redefined in the derived
class. Virtual functions are declared by preceding the class declaration with a keyword "virtual".
When a virtual function is declared C++ decides to execute a function based on the type of object
pointed by the base pointer and not on the type of pointer.
Example:

#include <iostream.h> class Bclass


{
public:
void disp() { cout << " BASE BASE\n" ; }
virtual void sh() { cout << "base base\n"; }

}; class Dclass : public Bclass


{
public:
void disp() { cout << "DERIVED DERIVED\n"; }
void sh() { cout << "derived derived\n"; }
}; int main()
{
Bclass B;
Dclass D;
Bclass *ptr;
cout << "ptr points to base class\n" ;
ptr = &B;
ptr->disp();
ptr->sh();
cout << "ptr points derived class\n";
ptr = &D;
ptr->disp();
ptr->sh();
return 0;
}

Result:

ptr points to base class


BASE BASE
base base
ptr points derived class
BASE BASE
derived derived
In the above example, the base ptr is used point the object D. Since the "sh()" function has a
derived version in the form of a virtual function, it displays the base class version of "sh()".
A virtual function makes its class a polymorphic base class. Derived classes can override
virtual functions. Virtual functions called through base class pointers/references will be
resolved at run-time. That is, the dynamic type of the object is used instead of its static type:
Derived d;

Base& rb = d;
// if Base::f() is virtual and Derived overrides it, Derived::f() will be called
rb.f();
A pure virtual function is a virtual function whose declaration ends in =0:
class Base {
// ...
virtual void f() = 0;
// ...
A pure virtual function makes the class it is defined for abstract. Abstract classes cannot be
instantiated. Derived classes need to override/implement all inherited pure virtual functions. If
they do not, they too will become abstract.
In C++, a class can define a pure virtual function that has an implementation. (What that's good
for is debatable.)

Abstract Class
Abstract Class is a class which contains atleast one Pure Virtual function in it. Abstract classes
are used to provide an Interface for its sub classes. Classes inheriting an Abstract Class must
provide definition to the pure virtual function, otherwise they will also become abstract class.
Characteristics of Abstract Class
1. Abstract class cannot be instantiated, but pointers and refrences of Abstract class type can
be created.
2. Abstract class can have normal functions and variables along with a pure virtual function.
3. Abstract classes are mainly used for Upcasting, so that its derived classes can use its
interface.
4. Classes inheriting an Abstract Class must implement all pure virtual functions, or else
they will become Abstract too.
Pure Virtual Functions
Pure virtual Functions are virtual functions with no definition. They start with virtual keyword
and ends with= 0. Here is the syntax for a pure virtual function,
virtual void f() = 0;
Example of Abstract Class
class Base
//Abstract base class
{
public:
virtual void show() = 0;
//Pure Virtual Function

};
class Derived:public Base
{
public:
void show()
{ cout << "Implementation of Virtual Function in Derived class"; }
};
int main()
{
Base obj;
//Compile Time Error
Base *b;
Derived d;
b = &d;
b->show();
}
Output : Implementation of Virtual Function in Derived class
In the above example Base class is abstract, with pure virtual show() function, hence we cannot
create object of base class.
Why can't we create Object of Abstract Class ?
When we create a pure virtual function in Abstract class, we reserve a slot for a function in the
VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the VTABLE will
be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of
object for such class and will display an errror message whenever you try to do so.
Pure Virtual definitions
Pure Virtual functions can be given a small definition in the Abstract class, which you
want all the derived classes to have. Still you cannot create object of Abstract class.
Also, the Pure Virtual function must be defined outside the class definition. If you will
define it inside the class definition, complier will give an error. Inline pure virtual
definition is Illegal.
class Base
//Abstract base class
{
public:
virtual void show() = 0;
//Pure Virtual Function
};

void Base :: show()


//Pure Virtual definition
{
cout << "Pure Virtual definition\n";
}
class Derived:public Base
{
public:
void show()
{ cout << "Implementation of Virtual Function in Derived class"; }
};
int main()
{
Base *b;
Derived d;
b = &d;
b->show();
}
Output :
Pure Virtual definition
Implementation of Virtual Function in Derived class

Operator overloading using friend function and member function ?

#include<iostream.h>
#include<conio.h>
class base
{
int val1,val2;
public:
void get()
{
cout<<"Enter two values:";
cin>>val1>>val2;
}
friend float mean(base ob);
};

float mean(base ob)


{
return float(ob.val1+ob.val2)/2;
}
void main()
{
clrscr();
base obj;
obj.get();
cout<<"\n Mean value is : "<<mean(obj);
getch();
}
Output:
Enter two values: 10, 20
Mean Value is: 15

Binary operator overloding using the member function in c++


#include <iostream>
#include <conio.h>
using namespace std;
class Complex
{
int real,img;
public:
Complex() //default constructor
{
real=0;
img=0;
}
Complex(int r,int ig) //Parametrized constructor
{
real=r;
img=ig;
}
Complex operator + (Complex &c) //Memory consumption is minimised by the use of &
{
//Class name as the derived type
Complex t;

t.real=real+c.real;
t.img=img+c.img;
return t;
}
void show()
{
cout<<real<<"+i"<<img<<endl;
}
};
int main()
{
Complex c1(5,2),c2(7,3),c3;
c1.show();
c2.show();
c3=c1+c2;//need a default constructor to initialize the values for c3
c3.show();
getch();
}
What is an inline function? What it is used? In what situation inline function are not
recommended?
C++ inline function is powerful concept that is commonly used with classes. If a function is
inline, the compiler places a copy of the code of that function at each point where the function is
called at compile time.
Any change to an inline function could require all clients of the function to be recompiled
because compiler would need to replace all the code once again otherwise it will continue with
old functionality.
To inline a function, place the keyword inline before the function name and define the function
before any calls are made to the function. The compiler can ignore the inline qualifier in case
defined function is more than a line.
A function definition in a class definition is an inline function definition, even without the use of
the inlinespecifier.
Following is an example, which makes use of inline function to return max of two numbers:
#include <iostream>
using namespace std;
inline int Max(int x, int y)
{

return (x > y)? x : y;


}
// Main function for the program
int main( )
{
cout << "Max (20,10): " << Max(20,10) << endl;
cout << "Max (0,200): " << Max(0,200) << endl;
cout << "Max (100,1010): " << Max(100,1010) << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Max (20,10): 20
Max (0,200): 200
Max (100,1010): 1010

Inline functions are faster because you don't need to push and pop things on/off the stack like
parameters and the return address; however, it does make your binary slightly larger.
Does it make a significant difference? Not noticeably enough on modern hardware for most. But
it can make a difference, which is enough for some people.
Marking something inline does not give you a guarantee that it will be inline. It's just a
suggestion to the compiler. Sometimes it's not possible such as when you have a virtual function,
or when there is recursion involved. And sometimes the compiler just chooses not to use it.
I could see a situation like this making a detectable difference:
inline int aplusb_pow2(int a, int b) {
return (a + b)*(a + b) ;
}
for(int a = 0; a < 900000; ++a)
for(int b = 0; b < 900000; ++b)
aplusb_pow2(a, b);
Inline function is the optimization technique used by the compilers. One can simply prepend
inline keyword to function prototype to make a function inline. Inline function instruct compiler
to insert complete body of the function wherever that function got used in code.
Advantages :-

1) It does not require function calling overhead.


2) It also save overhead of variables push/pop on the stack, while function calling.
3) It also save overhead of return call from a function.
4) It increases locality of reference by utilizing instruction cache.
5) After in-lining compiler can also apply intraprocedural optmization if specified. This is the
most important one, in this way compiler can now focus on dead code elimination, can give more
stress on branch prediction, induction variable elimination etc..
Disadvantages :1) May increase function size so that it may not fit on the cache, causing lots of cahce miss.
2) After in-lining function if variables number which are going to use register increases than they
may create overhead on register variable resource utilization.
3) It may cause compilation overhead as if some body changes code inside inline function than
all calling location will also be compiled.
4) If used in header file, it will make your header file size large and may also make it unreadable.
5) If somebody used too many inline function resultant in a larger code size than it may cause
thrashing in memory. More and more number of page fault bringing down your program
performance.
6) Its not useful for embeded system where large binary size is not preferred at all due to
memory size constraints.
Performance : Now covering the topic which most the people are interested in the "Performance".
In most of the cases Inline function boost performance if used cautiously as it saves lots of
overhead as discussed in our Advantages section above but as we have also discussed its
disadvantages one need to be very cautious while using them. Today's modern compiler inline
functions automatically, so no need to specify explicitly in most of the cases. Although placing
inline keyword only gives compiler a hint that this function can be optimized by doing in-lining,
its ultimately compiler decision to make it inline. Though there are ways to instruct compiler too,
for making a function call inline like one can use __forceinline to instruct compiler to inline a
function while working with microsoft visual c++. I suggest not to use this keyword until you are
very sure about performance gain. Making a function inline may or may not give you
performance boost, it all depends on your code flows too. Don't expect a magical performance
boost by prepending inline keyword before a function to your code as most of the compiler
nowadays does that automatically.
As we have seen inline function serves in terms of performacen but one has to use it with
extreme cautions.
I have prepared a few guidelines for its use.

Uses Guidelines :1) Always use inline function when your are sure it will give performance.
2) Always prefer inline function over macros.
3) Don't inline function with larger code size, one should always inline small code size function
to get performance.
4) If you want to inline a function in class, then prefer to use inkine keyword outside the class
with the function definition.
5) In c++, by default member function declared and defined within class get linlined. So no use
to specify for such cases.
6) Your function will not be inlined in case there is differences between exception handling
model. Like if caller function follows c++ structure handling and your inline function follows
structured exception handling.
7) For recursive function most of the compiler would not do in-lining but microsoft visual c++
compiler provides a special pragma for it i.e. pragma inline_recursion(on) and once can also
control its limit with pragma inline_depth.
8) If the function is virtual and its called virtually then it would not be inlined. So take care for
such cases, same hold true for the use of function pointers.

Command Line Arguments

In C++ it is possible to accept command-line arguments.


To pass command-line arguments into your program, C++ have a special argument list for main(
), which looks like this:
int main(int argc, char* argv[]) {
...
}
The first argument (argc) is the number of elements in the array, which is the second argument
(argv). The second argument is always an array of char*, because the arguments are passed
from the command line as character arrays (an array can be passed only as a pointer). Each
whitespace-delimited cluster of characters on the command line is turned into a separate array
argument. The following program (download) prints out all its command-line arguments by
stepping through the array:
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
cout << "argc = " << argc << endl;

for(int i = 0; i < argc; i++)


cout << "argv[" << i << "] = " << argv[i] << endl;
return 0;
}
Youll notice that argv[0] is the path and name of the program itself. This allows the program to
discover information about itself. It also adds one more to the array of program arguments, so a
common error when fetching command-line arguments is to grab argv[0] when you
want argv[1].
You are not forced to use argc and argv as identifiers in main( ), those identifiers are only
conventions (but it will confuse people if you dont use them). Also, there is an alternate way to
declare argv:
int main(int argc, char** argv) {
...
}
Both forms are equivalent.
All you get from the command-line is character arrays; if you want to treat an argument as some
other type, you are responsible for converting it inside your program. To facilitate the conversion
to numbers, there are some helper functions in the Standard C library, declared in <cstdlib>. The
simplest ones to use are atoi( ), atol( ), and atof( ) to convert an ASCII character array to
an int, long, and double, respectively. Heres an example using atoi( ) (the other two functions
are called the same way):
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char* argv[]) {
for(int i = 1; i < argc; i++)
cout << atoi(argv[i]) << endl;
return 0;
}
In this program, you can put any number of arguments on the command line. Youll notice that
the for loop starts at the value 1 to skip over the program name at argv[0]. Also, if you put a
floating-point number containing a decimal point on the command line, atoi( ) takes only the
digits up to the decimal point. If you put non-numbers on the command line, these come back
from atoi( ) as zero.

Container basics

An STL container is a collection of objects of the same type (the elements).

Container owns the elements.


o Creation and destruction is controlled by the container.

Two basic types of containers:

Sequences
o User controls the order of elements.
o vector, list, deque
Associative containers
o The container controls the position of elements within it.
o Elements can be accessed using a key.
o set, multiset, map, multimap

Container concepts
There are three main container concepts:

Container concepts are not as important for generic programming as iterator concepts.

There are fewer models.


Containers have important properties that are not described by the basic container
concepts.
o Properties that differentiate one container from another.
o In contrast, an iterator is almost fully described by the most refined concept it
models.
o More refined container concepts would have just one model.
Even the basic concepts can be too refined:
o boost::array
There are almost no generic algorithms taking a container as an argument.
o insert iterators

However, container concepts standardize basic features.

Consistent interface makes using them easier.


Fairly easy to replace one container with another.

The Container concept

Properties shared by all STL containers.

default constructor
copy constructor and assignment
o deep copy
swap
o a.swap(b) and swap(a, b)
o constant time
==, !=
o content-based equality: equal elements in same order
order comparisons
o lexicographic order: first inequal elements determine the order
vector<int> a, b;
// a = [1, 2, 3]
// b = [1, 3, 2]
assert(a < b);
begin(), end()
size(), empty(), max_size()
member types
o value_type
o reference (to the value type)
o const_reference
o iterator
o const_iterator
o difference_type (as with iterators)
o size_type (often unsigned type, usually size_t)

In addition, a reversible container has the properties:

rbegin(), rend()
member types
o reverse_iterator
o const_reverse_iterator

Sequences
Common properties of all sequence containers:

constructors
o Fill constructor Container(n, val) fills container with n copies of val.
o Default fill constructor Container(n) fills container with n default constructed
values.
o Range constructor Container(i, j) fills container with the contents of the iterator
range [i,j).
assign
o fill assignment assign(n, val)

o
o

range assignment assign(i, j)


old elements are assigned to or destroyed

insert
o
o
o

insert(p, val) inserts val just before the position pointed by iterator p.
insert(p, n, val) inserts n copies.
insert(p, i, j) inserts the contents of range [i,j).

erase

erase(p) erases the element pointed by iterator p.


erase(p,q) erases the range [p,q)
returns iterator to the position immediately following the erased element(s)
clear() erases all
o
o
o

vector
vector should be used by default as the (sequence) container:

It is more (space and time) efficient than other STL containers.


It is more convenient and safer than primitive array.
o automatic memory management
o rich interface

Properties of vector in addition to sequences:

v[i], at(i)
o v.at(i) checks that 0 <= i < v.size()
front(), back()
o return reference to the first and last element (not beyond last)
push_back(val)
o inserts val to the end
pop_back() removes
o removes the last element and returns it
resize
o change the number of elements in the vector
o resize(n) makes n the size; fills with default values if necessary
o resize(n, val) fills with val if necessary
capacity(), reserve(n) (see below)

Memory management

The elements are stored into a contiguous memory area on the heap.
o capacity() is the number of elements that fit into the area.
o size() is the actual number of elements. The remainder of the area is unused (raw
memory).
o reserve(n) increases the capacity to n without changing the size.
o The capacity is increased automatically if needed due to insertions.
Capacity increase may cause copying of all elements.

A larger memory area is obtained and elements are copied there.


Capacity increase by an insertion doubles the capacity to achieve amortized
constant time.
Capacity never decreases.
o Memory is not released.
o But the following gets rid of all extra capacity/memory:
vector<int> v;
...
vector<int>(v).swap(v); // copy and swap
Use &v[0] to obtain a pointer to the memory area.
o May be needed as an argument to non-STL functions.
vector<char> v(12);
strcpy(&v[0], "hello world");
o
o

Limitations of vector

Insertions and deletions in the beginning or in the middle are slow.


o Requires moving other elements.
o Prefer push_back() and pop_back().
o Insert or erase many elements at a time by using the range forms
of insert and erase.
Insertions and deletions invalidate all iterators, and pointers and references to the
elements.
vector<int> v;
...
vector<int> b = v.begin();
v. push_back(x);
find(b, v.end()); // error: b is invalid

deque
deque stands for double-ended queue. It is much like vector.

Differences to vector
o Insertion and deletion in the beginning in (amortized) constant time.
push_front, pop_front
o Slower element access and iterators.
o No capacity() or reserve(n) but also less need for them.
o Insertions and deletions to the beginning and end do not invalidate pointers and
references to other elements.
But iterators may be invalidated.
o deque<int> d(5,1);
o deque<int>::iterator i = d.begin() + 2;
o int* p = &*i;
o d.push_front(2);
o int x = *p; // OK

int y = *i; // error: i may be invalid

Memory management
deque stores the elements something like this:

Element access and iterators are more complicated.


Fast insertions and deletions to the beginning.
Handles size changes gracefully: - Capacity increases or decreases one block at a time.
Memory area is not contiguous.

list
The third standard sequence container is list. The underlying data structure is a doubly-linked
list:

No random access.
Fast insertion and deletion anywhere.
Insertions and deletions do not invalidate iterators, pointers or references to other
elements.

Member functions in addition to sequence:

push_front, pop_front
push_back, pop_back
splice
o c1.splice(i1, c2) removes all elements from list c2 and inserts them at
position i1 in list c1.
o c1.splice(i1, c2, i2) removes the element pointed by i2 from c2 and inserts it at
position i1 in list c1.
o c1.splice(i1, c2, i2, j2) removes the range [i2,j2) from c2 and inserts it at
position i1 in list c1.
o In the last two cases, c1 and c2 can be the same list.
o constant time
o Iterators, pointers and references keep pointing to the same element even if it is
moved to a different list.
template <class T, class A> // A is allocator
void catenate (list<T,A>& c1, list<T,A>& c2) {
c1.splice(c1.end(), c2);
}

member versions of STL algorithms


o reverse, sort, merge, remove, remove_if, unique
o In some cases, like sort, the algorithm would not work for lists because it requires
random access iterators.
o With the member versions, iterators, pointers and references keep pointing to the
same element, unless that element is deleted.

list<int> c;
c.push_back(10);
c.push_back(20);
c.push_back(30);
list<int>::iterator i = c.begin();
assert(*i==10); // i points to the first element: 10
c.reverse();
assert(*i==10); // i continues to point to 10
// which is now to the last element
reverse(c.begin(), c.end());
assert(*i==30); // i still points to the last element
// which now contains 30
string
string class was designed before STL, but STL container properties were added to it later. It is
similar to vectors; the differences include:

only char as element type


many additional operations
o concatenation (operator+, append)
o I/O (<<, >>, getline)
o C-string conversions
o substr, compare, find, replace
o Many operations can take C-string or substring as an argument.
o Many of the operations could be replaced with STL algorithms.
Many implementations have optimizations:
o reference counting with COW (copy on write)

short string optimization

vector<bool>
vector<bool> has some special properties.

Elements are stored as bits in a bit vector.


o very space-efficient
o some operations may be slow
It is not possible to have a pointer or a reference to a bit.
o operator[], front(), back(), and iterator's operator* do not return a reference but
a proxy object that behaves almost like a reference but not quite.
o Taking address of a proxy and assigning it to a reference is not possible.
vector<bool> v;
// ...
bool* p = &v[0]; // illegal
bool& r = v.back(); // illegal
o Otherwise a proxy can be used on either side of an assignment.
bool tmp = v[0];
v[0] = v[1];
v[1] = tmp;
o Does not satisfy all container requirements and iterators do not satisfy all
requirements of random access iterators.
flip
o v.flip() flips all bits
o flip one bit: v[1].flip(), v.back().flip(), v.begin()->flip()

Associative containers
The STL standard associative containers (set, multiset, map, multimap) allow access to elements
using a key:

For set and multiset element is its own key.


For map and multimap elements are of type pair<const Key, T>.
o pair is a standard template class defined as:
template <class T, class U>
struct pair {
T first;
U second;
// some constructors
};
set and map contain at most one element for each key.
multiset and multimap can contain many elements with the same key.

The underlying data structure is a balanced search tree:

logarithmic access time


requires order comparisons of keys
iteration in key order
Iterators, pointers and references stay valid until the pointed to element is removed.

The order comparison

operator< by default but can be changed

struct my_less {
bool operator() (int a, int b) { return a < b; }
}

// all three sets have the same ordering:


set<int> s1; // default: operator< as key order
set<int, std::less<int> > s2;
set<int, my_less> s3;

1.
2.
3.
4.
5.
6.
7.
8.

Two keys are equivalent if neither is smaller than the other.


o operator== is not used for comparing keys.
o Ensures consistency of order and equivalence.
must be strict weak ordering:
irreflexivity: x<x is always false.
transitivity: (x<y) && (y<z) implies x<z.
transitivity of equivalence: if x equals y and y equals z, then x equals z.
// NOT strict weak ordering:
// 1 equals 2 and 2 equals 3 but 1 does not equal 3
struct clearly_less {
bool operator() (int a, int b) { return a < b-1; }
}
o asymmetry: x<y implies !(y<x).
Often mentioned as a requirement, but it is implied by 1. and 2.
Often called antisymmetry in STL literature, but asymmetry is the correct
mathematical term.

Common properties
In addition to properties of the Container concept, all associative containers have:

member types
o key_type
o key_compare
comparison operators
o key_comp() returns the key comparison operator
o value_comp() returns a comparison operator comparing elements not keys.
constructors
o Range constructor Container(i,j) fills container with the contents of the range [i,j).
o (All constructors accept a comparison object as an extra optional argument.)
insert
o insert(x)
o insert(i, x). Iterator i is a hint pointing to where the search for insertion position
should start.
Allows insert_iterator to operate on associative containers.
o range insert insert(i, j)
o For set and map insertions are not done if the key is already there.
erase
o erase(k) erases all elements with key k
o erase(i) erase element pointed to by i
o range erase erase(i,j)
searching
o find(k) returns iterator to the element with key k or end() if no such element
o count(k)
o lower_bound(k) find first element with key not less than k
o upper_bound(k) find first element with key greater than k
o equal_range(k) returns pair<iterator,iterator> representing the range of element
with key k

set and multiset

Defined in header file set.


Implement the abstract data structures of set and multiset.
There are no additional member operations.

// count distinct words


set<string> words;
string s;
while (cin >> s) words.insert(s);
cout << words.size() << " distinct words\n";
There are no member operations for set intersection, union, etc. However, the following generic
algorithms work on any sorted range, including [s.begin(),s.end()) for a set or multiset s:

includes
set_intersection
set_union
set_difference
set_symmetric_difference

string str1("abcabcbac");
string str2("abcdabcd");

multiset<char> mset1(str1.begin(), str1.end());


multiset<char> mset2(str2.begin(), str2.end());

multiset<char> result;
set_intersection (mset1.begin(), mset1.end(),
mset2.begin(), mset2.end(),
inserter(result, result.begin()) );

copy(result.begin(), result.end(), ostream_iterator<char>(cout));


// outputs: "aabbcc"
map and multimap

Defined in header file map.


multimap has no additional operations, map has one, operator[].
The elements are pairs, which can make insertion and access slightly awkward.
o operator[] is the most convenient way:
map<string, int> days;
days["january"] = 31;
days["february"] = 28;
// ...
days["december"] = 31;
if (leap_year) ++days["february"];
cout << "February has " << days["february"] << " days.\n";

multimap does not have operator[]. The helper function make_pair is useful:
multimap<string, string> children;
children.insert(make_pair("Jane","Ann"));
children.insert(make_pair("Jane","Bob"));
children.insert(make_pair("Bob","Xavier"));
// ...
o

typedef multimap<string, string>::iterator iterator;


pair<iterator,iterator> answer;
answer = children.equal_range("Jane");
cout << "Jane's children:";
for (iterator i = answer.first; i != answer.second; ++i)
cout << " " << i->second;

Container adaptors
The container adaptors stack, queue, priority_queue are containers implemented on top of
another container.
They provide a limited set of container operations:

member types value_type and size_type, container_type


basic constructors, destructors and assignment
contruction from the underlying container adaptor(const container&)
comparison operators
size(), empty()

Stack
stack can be implemented on top of vector, deque or list.

The default is deque.

// these are equivalent


stack<int> st1;
stack<int, deque<int> > st2;
Additional operations:

constructor stack(const container&)


push(val)
top()
pop()

Queue
queue can be implemented on top of deque or list.

The default is deque.

Additional operations:

front()
back()
push(val)
pop()

Priority queue
priority_queue can be implemented on top of deque or vector.

The default is vector.

Uses order comparison operators of elements similar to the associative containers.


// these are equivalent
priority_queue<int> pq1;
priority_queue<int, vector<int> > pq2;
priority_queue<int, vector<int>, less<int> > pq3;
Additional operations:

range constructor
comparison object as an extra optional argument of constructors
push(val)
top() returns the largest element
pop() removes the largest element

There is no method for changing the priority of an element or removing an element that is not the
largest.

Sufficient for some applications like event simulation.


Not sufficient for others like Dijkstra's algorithm.

Hash tables

The standard has no containers using hashing, but they are a common extension. They are also
included in the Technical Report on C++ Standard Library Extensions, commonly known
as TR1, an extension of the standard library likely to be included in the next C++ standard:

unordered_set
unordered_multiset
unordered_map
unordered_multimap

More details can be found in the proposal.


Container elements
The type of container elements should always be a model of the Assignable concept:

Normally behaving copy constructor and copy assignment.


Never store into a container types that are not assignable:
o references (no assignment)
o std::auto_ptr (abnormal copy behavior)

Some member functions have additional requirements:

default constructor
o default fill constructor Container(n)
equality comparisons
o containers's operator==
order comparisons
o container's operator<
o associative container with default order comparison

Pointers in containers
Pointers as container elements require special care. There two kinds of pointers:

Pointers that do not own the object they point to.


o Example: the same element in multiple containers.
for example, different iteration orders
One container stores the elements, others store pointers to the elements.
o Prefer iterators to pointers.
They enable container manipulation.
o Be careful about validity
With deque use pointers instead of iterators if there are insertions or
deletions at the beginning or the end.
With vector use index if there are insertions or deletions at the end.
Pointers that own the element they point to.
o Example: polymorphic container:

struct animal {
virtual ~animal() {};
virtual void eat() =0;
// ...
}
struct baboon : animal {
// ...
}
struct lion : animal {
// ...
}
// ...
vector<animal*> zoo;
zoo.push_back(new baboon);
zoo.push_back(new lion);
zoo[1]->eat();
o Such pointers are problematic elements.
Containers take care that the destructor of an element is called, when the
element is erased (or the container is destroyed).
But an owning pointer's destructor does not do what it should: destroy the
pointed to object and release the memory.
The user of the container must ensure that the pointed to objects are
properly destroyed and freed. This is inconvenient and error-prone.
Achieving exception safety is difficult.
o Better to use a smart pointer, whose destructor does the right thing.
auto_ptr has the right kind of destructor, but unfortunately the wrong kind
of copy constructor and assignment.
Use boost::shared_ptr if possible.
o typedef boost::shared_ptr<animal> animal_ptr;
o vector<animal_ptr> zoo;
o
o
o
o
o
o

animal_ptr p(new baboon);


zoo.push_back(p);
p.reset(new lion);
zoo.push_back(p);
zoo[1]->eat();

Exception safety
Exceptions are a common error reporting mechanism in C++. The elements of STL containers
are allowed to throw exceptions (except in destructors). In particular, if a copy of an element

fails and throws an exception during a container operation, one of the following guarantees are
provided:

Strong guarantee: The container operation is cancelled, and the container's state is as if
the operation was never called.
o Most list operations.
o All single element operations on lists and associative containers.
o push and pop operations on vector and deque.
Basic guarantee: There are no memory leaks, and the container is in a consistent s

Processor directives in c++


The preprocessors are the directives, which give instruction to the compiler to preprocess the information before
actual compilation starts.
All preprocessor directives begin with #, and only white-space characters may appear before a preprocessor directive
on a line. Preprocessor directives are not C++ statements, so they do not end in a semicolon (;).
You already have seen a #include directive in all the examples. This macro is used to include a header file into the
source file.
There are number of preprocessor directives supported by C++ like #include, #define, #if, #else, #line, etc. Let us see
important directives:

The #define Preprocessor:


The #define preprocessor directive creates symbolic constants. The symbolic constant is called amacro and the
general form of the directive is:
#define macro-name replacement-text
When this line appears in a file, all subsequent occurrences of macro in that file will be replaced by replacement-text
before the program is compiled. For example:
#include <iostream>
using namespace std;
#define PI 3.14159
int main ()
{
cout << "Value of PI :" << PI << endl;
return 0;
}
Now, let us do the preprocessing of this code to see the result, assume we have source code file, so let us compile it
with -E option and redirect the result to test.p. Now, if you will check test.p, it will have lots of information and at the
bottom, you will fine the value replaced as follows:
$gcc -E test.cpp > test.p

...
int main ()
{
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}

Function-Like Macros:
You can use #define to define a macro which will take argument as follows:
#include <iostream>
using namespace std;
#define MIN(a,b) (((a)<(b)) ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
cout <<"The minimum is " << MIN(i, j) << endl;
return 0;
}
If we compile and run above code, this would produce the following result:
The minimum is 30

Conditional Compilation:
There are several directives, which can use to compile selectively portions of your program's source code. This
process is called conditional compilation.
The conditional preprocessor construct is much like the if selection structure. Consider the following preprocessor
code:
#ifndef NULL
#define NULL 0
#endif
You can compile a program for debugging purpose and can debugging turn on or off using a single macro as follows:
#ifdef DEBUG
cerr <<"Variable x = " << x << endl;
#endif
causes the cerr statement to be compiled in the program if the symbolic constant DEBUG has been defined before
directive #ifdef DEBUG. You can use #if 0 statment to comment out a portion of the program as follows:
#if 0
code prevented from compiling
#endif
Let us try the following example:

#include <iostream>
using namespace std;
#define DEBUG
#define MIN(a,b) (((a)<(b)) ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif
#if 0
/* This is commented part */
cout << MKSTR(HELLO C++) << endl;
#endif
cout <<"The minimum is " << MIN(i, j) << endl;
#ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;
#endif
return 0;
}
If we compile and run above code, this would produce the following result:
Trace: Inside main function
The minimum is 30
Trace: Coming out of main function

The # and ## Operators:


The # and ## preprocessor operators are available in C++ and ANSI/ISO C. The # operator causes a replacementtext token to be converted to a string surrounded by quotes.
Consider the following macro definition:
#include <iostream>
using namespace std;
#define MKSTR( x ) #x
int main ()
{
cout << MKSTR(HELLO C++) << endl;
return 0;
}
If we compile and run above code, this would produce the following result:
HELLO C++
Let us see how it worked. It is simple to understand that the C++ preprocessor turns the line:

cout << MKSTR(HELLO C++) << endl;


into the following line:
cout << "HELLO C++" << endl;
The ## operator is used to concatenate two tokens. Here is an example:
#define CONCAT( x, y )

x ## y

When CONCAT appears in the program, its arguments are concatenated and used to replace the macro. For
example, CONCAT(HELLO, C++) is replaced by "HELLO C++" in the program as follows.
#include <iostream>
using namespace std;
#define concat(a, b) a ## b
int main()
{
int xy = 100;
cout << concat(x, y);
return 0;
}
If we compile and run above code, this would produce the following result:
100
Let us see how it worked. It is simple to understand that the C++ preprocessor transforms:
cout << concat(x, y);
into the following line:
cout << xy;

Predefined C++ Macros:


C++ provides a number of predefined macros mentioned below:
Macro

Description

__LINE__

This contain the current line number of the program when it is being
compiled.

__FILE__

This contain the current file name of the program when it is being
compiled.

__DATE__

This contains a string of the form month/day/year that is the date of the
translation of the source file into object code.

__TIME__

This contains a string of the form hour:minute:second that is the time at


which the program was compiled.

Let us see an example for all the above macros:


#include <iostream>
using namespace std;
int main
{
cout
cout
cout
cout

()
<<
<<
<<
<<

"Value
"Value
"Value
"Value

of
of
of
of

__LINE__
__FILE__
__DATE__
__TIME__

:
:
:
:

"
"
"
"

<<
<<
<<
<<

__LINE__
__FILE__
__DATE__
__TIME__

<<
<<
<<
<<

endl;
endl;
endl;
endl;

return 0;
}
If we compile and run above code, this would produce the following result:
Value
Value
Value
Value

of
of
of
of

__LINE__
__FILE__
__DATE__
__TIME__

:
:
:
:

6
test.cpp
Feb 28 2011
18:52:48

Difference between associate and sequence container?

Scope resolution operator

Scope resolution operator in c++


Scope resolution operator(::) is used to define a function outside a class or when we want to use
a global variable but also has a local variable with same name.

C++ programming code


#include <iostream>
using namespace std;
char c = 'a';

// global variable

int main() {
char c = 'b';

//local variable

cout << "Local c: " << c << "\n";


cout << "Global c: " << ::c << "\n";

//using scope resolution operator

return 0;
}

Scope resolution operator in class


#include <iostream>
using namespace std;
class programming {
public:
void output(); //function declaration
};
// function definition outside the class

void programming::output() {
cout << "Function defined outside the class.\n";
}
int main() {
programming x;
x.output();
return 0;
}

what is Void Pointer?


Void pointer or generic pointer is a special type of pointer that can be pointed at objects of any data type. A
void pointer is declared like a normal pointer, using the void keyword as the pointers type.
Pointers defined using specific data type cannot hold the address of the some other type of variable i.e., it is
incorrect in C++ to assign the address of an integer variable to a pointer of type float.
Example:
float *f; //pointer of type float
int i; //integer variable
f = &i; //compilation error

The above problem can be solved by general purpose pointer called void pointer.
Void pointer can be declared as follows:
void *v // defines a pointer of type void

The pointer defined in this manner do not have any type associated with them and can hold the address of any
type of variable.
Example:
void *v;
int *i;
int ivar;
char chvar;
float fvar;
v = &ivar; // valid
v = &chvar; //valid
v = &fvar; // valid
i = &ivar; //valid
i = &chvar; //invalid
i = &fvar; //invalid

You might also like