Slides On C++
Slides On C++
Polymorphis
OOP Object
m
Class Inheritance
Internal
Circuit
Switc
h Bulb
Object
readData(
)
changeDat Dat
a() a
deleteDat
a()
Fig:
Encapsulation
Compiled By Bipin Thapa Magar 9
Concept/Features of
OOP
3. Object
Runtime entities that are identifiable with some characteristic and
behavior
Appl
e
Fig: Object
Compiled By Bipin Thapa Magar 10
Concept/Features of
OOP
4. Class
Group of objects that share common properties
It is like a user defined data type with data and functions
Objects are like variables to class. A class can be used to make various
objects. It is similar to ‘int a’ where int is data type and ‘a’ is integer.
Fruits
Fig:
Compiled By Bipin Thapa Magar 12
Inheritance
Concept/Features of
OOP
6. Polymorphism
Meaning “Having different forms”
It means that an object or entity can act different based on the message
sent or action
Examples: Function overloading, Operator overloading
2 and 3
5
(Integers) Operator Overloading:
0.5 and 3
(Float and 3.5
integer)
Fig:
Compiled By Bipin Thapa Magar 13
Polymorphism
Concept/Features of
OOP
7. Dynamic Binding
The process of linking function call to the code to be executed in response
to the call is called binding.
Types: Static and Dynamic Binding
Static Binding: Operator and Function Overloading, which happens at
compile time
Dynamic Binding: Achieved through inheritance and happens during run
time.
Complex.set(10,
20)
• C++
• C#
• Java
• Smaltalk
• Eiiffel
• D
Read Yourself:
• History
• Basic Syntax/Example
Procedure features
OOP features
common to C and
C++
Features of
C++
1. Namespace:
• It is used for logical grouping of program elements like functions,
variables, classes, etc.
• Similar program elements are kept in a single namespace.
• If multiple programmers are working in a project and are unknown
of the naming convention used by others, there might exist
collision in names. So, the name are separated into namespace to
make sure there is no naming conflict between different modules
2. Classes:
• A class is a user defined data type to define variable (instance) of
object.
• It logically combines data and function in a single unit.
3. Derived Classes:
• If a new class is made by inheriting any existing class, it is known
as derived class.
• It increases code reusability.
Features of
C++
4. Access Controllers:
• The keywords “public, private and protected” are known as access
controllers
• They define whether the data or functions of a class or object can
be accessed from outside of the class or not
• Public can access from anywhere
• Private cannot access outside of class
• Protected can be accessed by the class itself and its derived class
7. Reference variable:
• It is an alternative name given to a variable and used for passing
argument by reference.
8. Function overloading:
• Same function name is used for different operation.
• The operation depends upon the arguments provided to the
function.
9. Default arguments:
• If we don’t supply any arguments to a function, default value are
passed as arguments.
• Default value are set during function declaration.
Features of
C++
10. Inline function:
• If functions are small and has very small execution code, the
underlying code can be directly inserted to the function call. During
compile time, the compiler replaces the function call with the code
to reduce program execution time and increase efficiency.
C C++
1. It follows procedural programming 1. It is multi-paradigm language(both POP and
paradigm. OOP)
2. Follows top-down approach of program 2. Follows bottom-up approach of program
design. design.
3. Data are not secure. 3. Data are secure because of OOP features
like data hiding.
4. Functions are the building blocks of C 4. C++ are object-driven, and objects are
program and so it is function driven. building blocks of C++.
5. C doesn’t support function overloading. 5. C++ enables function overloading with the
help of polymorphism.
6. The namespaces feature is absent in C. 6. C++ allows namespace feature.
7. C doesn’t allow use of reference variables. 7. C++ allows use of reference variables
8. C programs are faster to compile. 8. C++ programs are relatively slower to
compile.
C++ versus C
C C+
#include<stdio.h> +
#include<iostream>
#include<conio.h> using namespace std;
Include File
Class Declaration
Digit: 0-9
Letters: A-Z , a-z
White Spaces: Blank Space, Horizontal Tab, Carriage Return,
Newline, Form Feed
Special Symbols: Space + - * / \ % ^ ( ) { } [ ] = < > , ‘ “ $ & | !
~ : ? _ # <= >=
Other Characters: C++ can process any of the 256 ASCII character
as data or literals
C++ Tokens
2. Identifiers:
User-defined names and consists of letters and digits, with a letter as a first
character.
C++ is case-sensitive and it treats lowercase and uppercase differently
Rules of defining identifier:
1. First character must be alphabet (or underscore)
2. Must consist of only letters, digits or underscore
3. Cannot use a keyword
4. Must not contain white space or special character
Examples:
Sagarmatha, _ram, bei1, oop_CPP
Invalid identifiers:
1Ram First character cant be a digit
continue keyword
Sagar-matha ‘-’ not allowed
C++ Tokens
3. Literals:
Also known as constants
a. Integer Constant:
Whole numbers without any fractional part.
An integer constant must have at least one digit and must not contain
any decimal point
It can contain +ve or –ve sign. If no sign exists, it is considered as
positive.
Three types: Decimal(Base 10), Octal(Base 8) and Hexadecimal (Base
16)
Decimal starts with a digit other than zero unless the digit is 0. eg:
+24, -16
Octal number ranges from 0 to 7 and always start with zero. Eg: 12 in
decimal is written as 014 in octal.
Hexadecimal starts with 0x or 0X. Eg: 20 in decimal is written as 0x14
in hexadecimals
b. Character constants:
Single character closed in single quotes.
eg: ‘a’, ‘s’
C++ Tokens
c. Floating Constant:
Numbers having fractional parts
Fractional form and exponential form
Fractional form must have at least one digit before a decimal point and at
least one digit after the decimal point. It can be positive or negative. Eg: 10.0,
-12.125, -0.061012
Invalid fractional form: 11(No decimal point), 11. (No digit after decimal
point), +7/2 (Illegal symbol /)
Exponential form has two parts: mantissa and an exponent. The mantissa
must be either an integer or a proper real constant. The mantissa is
followed by a letter E. The exponent must be an integer. Eg: 1.0128 x 10 3 =
1.0128 E03 where mantissa=1.0128 and exponent is 03.
d. String Literals:
Sequence of characters surrounded by double quotes.
Each string literal is automatically added with terminating character ‘\0’
Eg: “Ram”
C++ Tokens
4. Punctuators:
The following characters are used as punctuators ( also known as
separators) in C++:
[ ] ( ) { } , ; : * … = #
5. Operators:
Operators are tokens that trigger some computation or action when applied
to variables and other objects in an expression.
a. Arithmetic Operators
Addition(+), Subtraction(-), Multiplication(*), Division(/) and
remainder(%)
b. Increment/Decrement Operators
Increment Operator(++) and Decrement Operator (- -)
Pre: (++a) and Post: (a++)
a=5, c=5;
sum=a + (++c); sum=11;
sum=a + (c++); sum=10;
C++ Tokens
c. Relational Operators:
Operator Meaning
< is less than
<= is less than or equal to
> Is greater than
>= is greater than or equal to
== is equal to
!= not equal to
d. Logical Operators:
Operator Meaning
&& Logical AND
|| Logical OR
! Logical NOT
cout<<“\nBitwise
AND:”<<c;
cout<<“\nBitwise OR:”<<d;
Output cout<<“\nBitwise XOR:”<<e;
cout<<“\nBitwise
Bitwise AND: 4 leftshift:”<<f;
Bitwise OR: 15 cout<<“\nBitwise
Bitwise XOR: 11 rightshift:”<<g;
Bitwise leftshift: 28
Bitwise rightshift: 1 return 0;
}
C++ Tokens
2. Derived Types:
array, functions, pointers, references, constants, classes, structures, unions and
enumerations
C++ Data Types
1. Implicit Conversion:
C++ automatically converts any intermediate value to proper type so
that expression can be evaluated without losing any significance.
Example:
int a,b;
float c;
.
.
cout<<a+b+c; // the result becomes float
2. Explicit Conversion:
It is the process in which we force a type conversion.
Syntax: (type-name) expression
Example:
x= (int) 7.5; // it gets converted to 7
Statemen
ts
The instructions given to the computer to perform any kind of action are
called statements.
Statements are terminated with a semicolon(;).
Every expression, making decision or repeating action is known as
statements.
Example:
#include<iostream>
If we want to insert some other file, we can insert the file by providing path :
#include “filename”
Eg:
#include “C:\\tc\\bin\\mydir\\filename”
Namespa
ce
Logical grouping of declarations
General Form:
namespace namespace_name{
//declaration of variable,function,class,etc;
}
Example:
namespace Rectangle{
int width;
int height;
void volume();
}
Rectangle::width=10;
If we don’t want to use that everytime, we can use the ‘using’ directive.
Namespa
ce
#include<iostream>
#include<iostream>
using namespace std;
using namespace std;
namespace Rectangle{
namespace Rectangle{
int width;
int width;
int height;
int height;
void volume();
void volume();
}
}
int main(){
int main(){
using namespace Rectangle;
Rectangle::width=2;
width=2;
Rectangle::height=4;
height=4;
Rectangle::volume();
volume();
return 0;
return 0;
}
}
void Rectangle::volume(){
void Rectangle::volume(){
cout<<“Volume is
cout<<“Volume is
“<<width*height;
“<<width*height;
}
Namespa
ce
namespace std:
namespace std{
istream cin;
ostream cout;
.
.
.
//other stuffs
}
The definition of cin, cout and all others is in “iostream”. So, if we don’t use
namespace, our code would look like this:
std::cout<<“Hello”;
cout<<“Hello”;
Namespa #include<iostream>
ce using namespace std;
Nested Namespace: namespace Function{
We can create another namespace inside a namespace as: namespace Data{
int x;
namespace NS1{ int y;
: //some members of NS1 }
namespace NS2{ void product(){
: //some members of NS2 using namespace Data;
int r; cout<<x*y;
} }
} void sum(){
using namespace Data;
Here, if we want to access the integer “r”, we do something like this: cout<<x+y;
}
NS1::NS2::r=10; }
int main(){
Function::Data::x=10;
Function::Data::y=3;
Function::product();
Function::sum();
}
Namespa
ce
Unnamed Namespace:
Unnamed namespace are those which donot have any
name.
#include<iostream>
using namespace std;
namespace{
int x;
namespace{
int y;
int x;
}
int y;
}
It is now globally accessible in the program. The above
program is actually equivalent to:
int main(){
x=10;
namespace $$${
y=20;
int x;
cout<< x*y;
int y;
return 0;
}
}
using namespace $$$;
Input/Output
Streams
1. Output Stream:
The output stream allows us to write operations on standard output
devices such as screen, disk, etc.
We use the object cout for output operation which is an object of
library class “ostream”. The “iostream” includes both “ostream” and
“istream”.
‘<<‘ is called insertion or put to operator and is overrided.
Syntax:
cout<<var1<<var2<<var3<<………<<varN;
Example:
cout<<“Hello”;
“Hello
Hello cout << ”
Screen
Input/Output
Streams
2. Input Stream:
The input stream allows us to perform read operations from standard
input devices such as keyboard, disk, etc.
We use the object cin for input operation which is an object of library
class “istream”. The “iostream” includes both “ostream” and
“istream”.
‘>>‘ is called extraction or get operator and is overrided.
Syntax:
cin>>var1>>var2>>var3>>………>>varN;
Example:
cin>>var_name;
variab
Hello cin >> le
Keyboa
rd
Manipulator
s
Certain instructions to input/output streams that modify the output in
various ways.
Included in the header file <iomanip>
Eg: endl, setw
endl:
Similar to “\n”
It sends a new line and flushes the stream i.e. puts all the pending
characters that is stored in internal buffer but not yet output.
Eg:
cout<<endl<<“Perimeter is”<<perimeter;
cout<<endl<<“Area is”<<area;
Output:
Perimeter is 9
Area is 20
Manipulator
s
setw:
It causes the number or string that follows it in the
stream to be printed within a field specified in the
argument.
Eg:
cout<<setw(n)<<var_name; Outpu
LOCATION
t
cout<<setw(5)<<num; POPULATION
#include<iostream>
This displays num with character width if num is less than 5 Patan
#include<iomanip>
character. 5425678
using namespace std; Khotang
int main(){ 47000
long pop1=5425678,pop2=47000,pop3=76890; Butwal 76890
cout<<setw(8)<<“LOCATION”<<setw(12)<<“POPULATIO
N”<<endl
<<setw(8)<<“Patan”<<setw(12)<<pop1<<endl
<<setw(8)<<“Khotang”<<setw(12)<<pop2<<endl
<<setw(8)<<“Butwal”<<setw(12)<<pop3<<endl
return 0;
}
Dynamic Memory Allocation with new
and delete
When we declare an array such as “int a[100]”, the compiler sets
aside the required memory but it might not be enough or it might
not be used during execution.
So, if situation arises where we are unsure of the memory required
during compile time, the memory allocation can be performed during
run time, which is known as dynamic memory allocation.
C++ uses new operator for dynamic memory allocation and delete
operator for dynamic memory de-allocation.
1. new:
The new operator obtains memory at runtime from the memory heap
from the operating system and returns the address of the obtained
memory.
It is designed keeping OOP in mind and throws an exception if
memory allocation fails.
Syntax:
int *iptr;
iptr= new int; //allocates space for single integer
iptr= new int[n]; //allocates space for an array of integer with n
elements
Dynamic Memory Allocation with new
and delete
2. delete:
When we allocate memory using new at runtime, the memory is
reserved even after it is not needed or after the scope of the variable
ends.
Syntax:
delete data_type_ptr; //releases a single dynamic variable
delete [ ]data_type_ptr; // releases dynamically created array
Example:
int *iptr;
iptr= new int[4];
. . . .
. . . .
delete iptr;
Reference variable
A reference variable is alias (alternative name) for a previously
defined variable.
Syntax:
data_type & referenceName= variableName;
Example:
int &a=b;
Illustration:
Read Yourself:
Function Call:
a. Call by value
b. Call by reference
We wont be talking about call by value because it is same as before. If you want, I can
show you an example.
Call by reference:
When a function is called by reference, then the formal parameter becomes reference
(aliases) to the actual parameters in the calling function.
During call by reference, the program doesn’t create a new copy of the variable but
refers to the same variable using a new name.
Note that we can only use variable but not constants during call by reference.
Functio
ns Call by reference
Call by reference in
C++
in C
#include<iostream> #include<iostream>
using namespace std; using namespace std;
void area(int *); void area(int &);
Address of
12 12 a
length
lengt a lengt
Functio
ns
Return by reference:
Like a function can have alias as an argument, a function can also return a reference.
For this, we have to pass by reference as local variable doesn’t have scope outside of
the function.
#include<iostream> int Large, small;
using namespace std; cout<<“\nEnter the value of c
and d”;
int & min(int &a, int &b) cin>>c>>d;
{ Large=max(c,d);
if(a<b) return a; small=min(c,d);
else return b; cout<<“\nLargest
} is:”<<Large;
cout<<“\nSmallest
int max(int &a, int &b) is:”<<small;
{
if(a>b) return a; //max(c,d)=-10; error
else return b; min(c,d)=-5;
} cout<<c<<d;
return 0;
int main(){ }
int c,d;
Functio
ns
}
Functio
ns
#include<iostream>
using namespace std;
void area(int); #include<iostream>
int main(){ using namespace std;
int length=12; void area(int);
area(length); int main(){
return 0; int length=12;
} cout<<length;
return 0;
inline void area(int a){ }
cout<<a;
}
Functio
ns
Default Argument:
We can assign some values to arguments during function declaration which
are known as default arguments.
Example:
float interest(float p, int time, float r=0.1)
#include<iostream>
using namespace std;
int main(){
interest(); //p=1000, t=5, r=0.1
interest(4000); //p=4000, t=5, r=0.1
interest(5000,10); //p=5000, t=10, r=0.1
interest(5000,10,0.14); //p=5000, t=10, r=0.14
return 0;
}
Functio
ns
Default Argument:
Note that we can only set an argument with default value if all the arguments
to its right have default values set.
i.e.
float interest(float p, int t, float r=0.14) // OK
float interest(float p, int t=10, float r) // error
float interest(float p, int t=10, float r=0.14) // OK
float interest(float p=1000, int t, float r=0.14) // error
Functio
ns
Function Overloading:
A function name having several definitions that are differentiable by the
number or the types of their arguments is function overloading.
When either the number or type of argument differs but the name is same,
the compiler treats each of them as different functions and selects and bind
each function individually during compile time.
So, it is called early-binding or static-binding or static-linking. It is also
known as compile-time polymorphism.
Example:
float add(int a, int b);
float add(float x, float y); //different type of argument
float add(int a, int b, int c); //different number of argument
Categories/Types:
1. Number of Arguments
2. Type of Argument
3. Number and Type of Argument
Functio
ns
1. Number of Arguments:
We can define same functions, which have different number of arguments.
#include<iostream> int main(){
using namespace std; add(5,10); //function 1
add(5,10,15); //function 2
void add(int a, int b){ //function 1 add(5,10,15,20); //function 3
cout<<a+b; return 0;
} }
void add(int a, int b, int c){
//function 2
cout<<a+b+c;
}
void add(int a, int b, int c, int d){
//function 3
cout<<a+b+c+d;
}
Functio
ns
2. Type of Argument
We can define same functions, which have different type of arguments.
int main(){
#include<iostream>
add(5,10); //function 1
using namespace std;
add(5,10.5); //function 2
add(5.4,10.6); //function 3
void add(int a, int b){ //function 1
return 0;
cout<<a+b;
}
}
void add(int a, float b){ //function 2
cout<<a+b;
}
void add(float a, float b){ //function
3
cout<<a+b;
}
Functio
ns
3. Type and Number of Argument
We can define same functions, which have different name as well as of
arguments.
int main(){
#include<iostream>
add(5,10); //function 1
using namespace std;
add(5,10.5); //function 2
add(5,10.6,15); //function 3
void add(int a, int b){ //function 1
return 0;
cout<<a+b;
}
}
void add(int a, float b){ //function 2
cout<<a+b;
}
void add(int a, float b, int c){
//function 3
cout<<a+b;
}
Arrays
Collection of variable of the same type that are reference by a common base.
Data:
table[0][0]=0 table[0][1]=0 table[0][2]=0
table[1][0]=1 table[1][1]=1 table[1][2]=1
Pointer
A pointer is a variable which holds a memory address of another variable in memory.
General Form:
type * var_name;
Example:
int *iptr; //creates an integer pointer 10 10 20 100
char *cptr; //creates an character pointer 0 0
i ipt
int i=10; r
iptr=&i;
*iptr=20; // The value of i becomes 20
Pointer Arithmetic:
iptr++; // iptr becomes 102 not 101
String
It is a character array that is terminated by null character ‘\0’.
General Form:
char string_name[size];
Example:
char name[10];
char name[11]=“SAGARMATHA”;
char name[11]={ ‘S’, ‘A’, ‘G’, ‘A’, ‘R’, ‘M’, ‘A’, ‘T’, ‘H’, ‘A’, ‘\0’ };
char name[]={ ‘S’, ‘A’, ‘G’, ‘A’, ‘R’, ‘M’, ‘A’, ‘T’, ‘H’, ‘A’, ‘\0’ }; //automatically creates
array of size 11
Normally, cin can be used to take input to string as well but it cant take whitespaces as
input.
i.e If we input “Hello World” as
cin>>str;
str only stores “Hello”.
So, we use a function getline() to store whitespaces as well.
cin.getline(str,20);
Accessing Member:
var1.day=27;
Unions
It is same as structure but the difference is all the members share the same memory so
that we can only use one member at a time.
#include<iostream>
using namespace std;
union data{
int x;
float y;
}; The size is: 4
int main(){ x=10
data d1; y=1.40 E-044
cout<<“The size x=12312
is:”<<sizeof(d1); y=11.2
d1.x=10;
cout<<“x=“<<d1.x;
cout<<“y=“<<d1.y;
d1.y=11.2;
cout<<“x=“<<d1.x;
cout<<“y=“<<d1.y;
return 0;
}
Enumeration
User defined data type which provides a way of attaching names to numbers.
General Form:
enum tag {enumerator’s list} variable-list;
Example:
enum days{sun,mon,tues};
days d1,d2;
In above list, default values are set as sun=0, mon=1 and tues=2.
class Complex{
float real;
float imaginary;
public:
void input(){
cout<<“\n Enter real and imaginary:”;
cin>>real>>imaginary;
}
void display(){
cout<<“\n Real:”<<real;
cout<<“\n Imaginary:”<<imaginary;
}
float magnitude(){
float m=sqrt(real*real + imaginary
*imaginary);
return m;
}
};
Objects
When we create a class, it only specifies the type of information that the object of this
class type will be containing.
Once class has been declared, we can create variables of that type by using class name:
class_name object1, object2, ….. , objectN;
class Complex{
int main(){
float real;
Complex c1,c2;
float imaginary;
c1.input();
public:
c1.display();
void input(){
cout<<c1.magnitud
cout<<“\n Enter real and imaginary:”;
e();
cin>>real>>imaginary;
}
}
void display(){
cout<<“\n Real:”<<real;
cout<<“\n Imaginary:”<<imaginary; Output:
}
float magnitude(){ Enter real and
float m=sqrt(real*real + imaginary imaginary: 3 4
*imaginary); Real: 3
return m; Imaginary: 4
} 5
Objects
Memory Allocation of Object:
c c
1 2
Rea 3 Rea
l l
Imagina 4 Imagina
ry ry
clas
s
input()
display()
magnitude
()
Access
Specifiers
1. public:
All the data members and member functions which are under public can be
accessed from anywhere using objects.
2. private:
All the data members and member functions which are under private can only be
accessed inside the class owning it.
The members which are private are hidden from outside world. Also, friends can
access private members which is discussed later.
At default, all the data members are private unless mentioned otherwise.
3. protected:
The protected members act the same as private members in normal case. It’s
significance can be seen while studying inheritance later on.
Constructors
A constructor is a member function of a class that is automatically called, when an
object of that class is created.
It has the same name as that of the class’s name and it is mainly used to initialize the
data members of the class.
It can be declared either inside or outside the class but note that it doesn’t have any
return type, not even void.
class Complex{
class Complex{ float real;
float real; float imaginary;
float imaginary; public:
public: Complex();
Complex(){ };
real=0; Complex::Complex(){
imaginary=0; real=0;
} imaginary=0;
}; }
Constructors
Types: class Complex{
1. Default Constructor float real;
2. Parameterized Constructor float imaginary;
3. Copy Constructor public:
Complex(){
1. Default Constructor: real=0;
A constructor with no parameter is called default constructor. imaginary=0;
Syntax: }
classname::classname(){ };
//body of constructor
}
If no constructor is defined, the compiler will automatically supply a default constructor.
Default constructor are used to initialize the data members with any dummy value.
Constructors
2. Parameterized Constructor:
The constructor that can take arguments are called parameterized
constructor.
It allows us to initialize the data members with different values when
they are created.
Syntax:
class Complex{
classname::classname( arguments ){
float real;
//Body of constructor
float imaginary;
}
public:
Note that if only parameterized constructor is created, the compiler
Complex(int a, int b){
doesn’t provide a default constructor so that we can only create
real=a;
objects by passing arguments.
imaginary=b;
i.e In given example,
}
Complex c2;
};
is invalid as no constructor handles it.
We can call constructor using two ways:
int main(){
1. Implicit call:
Complex c1(3,4);
Classname objectname(arglist)
//real=3, imaginary=4
Eg: Complex c1(3,4);
}
2. Explicit call:
Classname objectname = Classname(arglist)
Constructors
Temporary Instance:
We can create a temporary object of a class by invoking itsclass Complex{
constructor. float real;
It exists in memory only during execution and after that it dies.]
float imaginary;
public:
Constructor with primitive data type: Complex(int a, int b){
The default and parameterized constructor exists for primitive real=a;
data type. imaginary=b;
So, we can do the following: }
int a; //default constructor void display(){
int a(5); // parameterized constructor cout<<real<<ima
ginary;
}
};
int main(){
Complex c1(1,2);
Complex(3,4).display()
;
cout<<“Only c1 exists
Constructors
Constructor with default argument: class Complex{
We can give default arguments to constructor as shown: float real;
float imaginary;
public:
Note that we can create multiple constructors of a class using concept
of Complex(int a=3, int b=4){
function overloading. real=a;
class Complex{ imaginary=b;
float real; }
float imaginary; };
public:
Complex(){ int main(){
real=0; Complex c1;// real=3,
imaginary=0; imag=4
} Complex c2(1); // real=1,
Complex(int a, int b){ imag=4
real=a; Complex c3(1,2); // real=1,
imaginary=b; imag=2
} }
};
Constructors
Initialization list:
We can initialize data members as follows:
class Complex{
float real;
float imaginary;
public:
Complex(int a, int b) : real(a),
imaginary(b)
{ }
};
Constructors
3. Copy constructor:
The constructor which is called when we initialize an object with
another object of same class is known as copy constructor.
Default copy constructor:
It is the constructor which is built in default in every class when we
instantiate object with another object of same class.
We need not define any constructor. Default copy constructor is
invoked when we create an object with another object of same class.
It causes member-by-member copy of the objects.
class Complex{
float real; int main(){
float imaginary; Complex c1(3,4); //c1.real=3,
public: c1.imaginary=4
Complex(int a, int b){ Complex c2(c1); //c2.real=3,
real=a; c2.imaginary=4
imaginary=b; Complex c3=c1; //c3.real=3,
} c3.imaginary=4
}; }
Constructors
User defined copy constructor:
It takes a reference to an object of the same class as argument.
class Complex{
float real;
float imaginary;
public: int main(){
Complex(int a, int b){ Complex c1(3,4); //c1.real=3,
real=a; c1.imaginary=4
imaginary=b; Complex c2(c1); //c2.real=3,
} c2.imaginary=4
Complex(Complex &c) Complex c3=c1; //c3.real=3,
{ c3.imaginary=4
real=c.real; }
imaginary=c.imaginar
y;
}
};
Constructors
Order of constructor invocation:
Normally, constructor is invoked in the order they are defined.
public:
class A{ ABC( ){
public: cout<<“\n ABC class”;
A( ){ }
cout<<“\n A };
class”; int main(){
} ABC obj;
}; }
class B{
public:
B( ){
cout<<“\n B
class”; OUTPUT:
} B class
}; A class
class ABC{ ABC class
B b;
A a;
Destructor
s
The function which is called when an object of a class is destroyed is
called as Destructor.
General Form:
~ classname(){
}
class Complex{
float real;
float imaginary;
public:
int main(){
Complex( ){
Complex c1; //Constructor of c1 called
cout<<“Constructor
{
called”;
Complex c2; //Constructor of c2 called
}
} //Destructor of c2 called at end of block
~Complex( ){
} //Destructor of c1 called at end of block
cout<<“Destructor
called”;
}
};
Destructor
s
Characteristics:
They are invoked automatically when the objects are destroyed.
If a class has destructor, each object of that class will be de-initialized
before the object goes out of scope.
The Destructor doesn’t take any argument, which means that
destructors cannot be overloaded.
Destructor functions also obey all the access rules as other member
functions.
They cannot be inherited.
A destructor may not be static.
Member function may be called from within a destructor.
An object of class with a destructor cannot be a member of a union.
It is not possible to take the address of a destructor.
Others
1. Object as Function Arguments and Return type
2. Array of objects
3. Pointer to Objects and Member Access
Code is attached
Read the theory yourself
DMA for Objects and Object
Array
DMA for object is same as that of normal data type.
We use new and delete for DMA.
new:
className *pointer;
pointer=new className; //single object
pointer=new className[size]; //Array of object
delete:
delete[ ] pointer;
this
Pointer
It is the pointer which points to the current object, i.e. the object invoking the
member function.
Whenever a member function is called, the current object calling the function is
passed to this pointer.
Example:
this->dataMember;
this->memberFunction();
Static Data Member and static
member function
What is static??
Just like in C, static members are those which are unique in a class just like
normal member functions.c c
1 2
Rea 3 Rea
l l
Imagina 4 Imagina
ry ry
clas
s
Static
Member
input()
display()
magnitude
()
Static Data Member and static
member function
Static Data Member:
It is the variable which is globally available to all the objects of the class type.
It is used to store values which is common to the entire class.
Properties:
Only one copy of the member is created for entire class and is shared among all
the objects of the class.
It is visible only within the class, but its lifetime is the entire program.
Static Data member are declared inside the class but defined outside the
class using the keyword static.
class Sagarmatha{
static int count;
};
int Sagarmatha::count; //definition of static data member
to 0
Static Data Member and static
member function
Static Member Functions:
Those member functions which can only access static data members are called
static member functions.
Properties:
A static member function can only access static data member of the class.
It is invoked using the class name instead of the object name.
class Sagarmatha{
static int count;
int id;
….
static void show(){
cout<<count;
//cout<<id; error as id is not static
}
};
int Sagarmatha::count; //definition of static data member
to 0
Constant Member Functions and
Constant Object
Constant Member Functions:
If a member function of a class doesn’t alter any data in the class, this member
function is declared as a constant member functions using the keyword const.
Example:
void interest(int, int) const;
float interest(void) const;
The keyword const should be used in both declaration and definition.
A constant member function can only invoke other constant member functions of
same class.
class Sagarmatha{
int count;
public:
void show() const{
cout<<count;
count=2; //error as constant member functions cannot
alter data
}
};
Constant Member Functions and
Constant Object
Constant Objects:
The objects of any class can be defined constant using const keyword.
Constant objects cannot change any data member. So, to ensure that constant
objects can only call constant member functions.
class Sagarmatha{
Example: int count;
const Sagarmatha s1; public:
void input(){
count=1;
}
void show() const{
cout<<count;
count=2; //error as constant member functions cannot
alter data
}
};
int main(){
const Sagarmatha s1;
s1.show();
s1.input(); //error as it is not constant
}
Constant Member Functions and
Constant
mutable:
Object class Sagarmatha{
In some cases, there may arise mutable int count;
a condition where we create a public:
constant object but we need to void input(){
change certain data member. count=1;
In those cases, we define the }
data members as mutable. void change() const{
Example: count=2;
mutable int a; }
void show() const{
cout<<count;
count=2; //error as constant member functions cannot
alter data
}
};
int main(){
const Sagarmatha s1;
s1.show();
s1.input(); //error as it is not constant
s1.change(); //allowed as change() is const and it can alter
mutable data
Friend Function and Friend
Classes
Normally, the private and protected data members of a class can only be accessed by the
member functions of that class, but in some cases, we might need to access them from
outside. So, we define friend functions which can access the private and protected data
members.
Friend Function:
class Demo{
int id;
friend void check();
private:
….
public:
….
};
void check(){
Demo d;
d.id=2;
}
Friend Function and Friend
Classes
Friend Function:
It doesn’t have class scope, rather it depends upon its original declaration and definition.
It doesn’t require an object of the class for invoking. It can be called as normal functions.
Since it is non member function, it cannot access the members of the class directly and has
to use and object name.
It can be declared anywhere, private, public or protected in the class.
A function may be declared as friend to more than one class.
class B;
class A{
:
friend void exchange(A, B);
:
};
class B{
:
friend void exchange(A, B);
:
};
class B;
class A{
:
friend class B;
:
};
class B{
:
void someFunction(){
//can access all members of
A
A a;
a.someMember;
}
:
};
Operator Overloading
Using Constructor:
In this method, a constructor needs to be placed inside the destination class with argument
of source data type.
Syntax:
Class1(Class2 obj){
//statements
}
Using cast operator:
In this method, cast operator needs to be placed inside source class with type name of
destination class.
Syntax:
operator Class1() //inside Class2
//statements
}
Data Type Conversion
c. User Defined to User Defined
class Celsius;
class Fahrenheit{ void display(){
float F; cout<<endl<<C;
public: }
void input(){ };
cout<<“Enter Fahrenheit
temperature:”; Fahrenheit::operator Celsius(){
cin>>F; Celsius temp( (F-32)/1.8);
} return temp;
operator Celsius(); }
};
class Celsius{ int main(){
float C; Fahrenheit F1;
public: Celsius C1;
Celsius(){ } F1.input();
Celsius(float c1){ C1=F1;
C=c1; C1.display();
} }
class Polar{
float Rad; Rectangle(){ }
float Ang; Rectangle(Polar p){
public:
int main(){
Polar(){}; x=p.getRad()*cos(p.getAng());
Polar p1;
Polar(Rectangle);
cout<<“Enter value of
void input(){ y=p.getRad()*sin(p.getAng());
polar:”;
cin>>Rad>>Ang; }
p1.input();
} void input(){
void display(){ cin>>x>>y;
Rectangle r1;
cout<<“\ }
r1=p1;
nRadius:”<<Rad; void display(){
r1.display();
cout<<“\ cout<<“\nX :”<<x;
nAngle:”<<Ang; cout<<“\nY :”<<y;
Rectangle r2;
} }
Polar p2;
float getRad(){ float getX(){ return x; }
cout<<“\nEnter value in
return Rad; float getY(){ return y; }
rect:”;
} };
r2.input();
float getAng(){
p2=r2;
return Ang; Polar::Polar(Rectangle r){
p2.display();
} Rad=sqrt(r.getX()*r.getX()
}
}; +r.getY()*r.getY());
class Rectangle{ Ang=atan(r.getY()/r.getX());
float x; }
float y;
Data Type Conversion
Explicit:
There might be times when you donot want conversion to take place. In such times, if we are
using cast operator, we can simply remove it from code but constructor cannot be removed
trivially. In such case, they can be defined as explicit to prevent from type casting.
Eg: class XYZ{
int a;
public:
explicit XYZ(int m){
In the example shown, a=m;
XYZ obj(5); }
}; object.
is valid as it uses the contructor definition to create the
XYZ obj = 5;
is invalid although we studied that type cast allows us to create such object using
constructor. It is invalid because we used the ‘explicit’ keyword.
Inheritance
A derived class (sub class) is the class that inherits the properties of another class called
base class (super class).
Syntax:
class derivedClassName : visibilityMode BaseClassName{
: //members of derived class
};
Example:
Inheritance
class D : public B{ //public derivation
//members of D
};
class D : protected B{ //protected derivation
//members of D
};
class D : private B{ //private derivation
//members of D
};
class D : B{ //private derivation by default
//members of D
};
Visibility Modes
Inheritance
class Base{
protected:
int n;
public:
void input(){ int main(){
cout<<“\n Enter a value:”; Derived D1;
cin>>n; D1.input();
} D1.display();
}; system(“pause”);
class Derived: public Base{ return 0;
public: }
void display(){
cout<<“\n n=“<<n;
}
};
Member function overriding
Overriding and Overloading are two different things. In Overloading, we create a function
with same name but different type or number of arguments. In Overriding, we create
identical functions in both base and derived class.
If we create the members identical to the base class, the members of derived class override
its parent’s members and the members of base class are hidden.
class Base{
void input(){
protected:
cout<<“\n Enter a value in
int n;
Derived:”;
public:
cin>>n;
void input(){
}
cout<<“\n Enter a value in
void display(){
Base:”;
cout<<“\n n=“<<n;
cin>>n;
}
}
};
};
int main(){
class Derived: public Base{
Derived D1;
protected:
D1.input();
int n;
D1.display();
public:
}
Member function overriding
If we want to access the hidden members of base class, we use:
baseClassName::member
We can use it inside derived class or main().
void input(){
class Base{ Base::input();
protected: cout<<“\n Enter a value in
int n; Derived:”;
public: cin>>n;
void input(){ }
cout<<“\n Enter a value in void display(){
Base:”; cout<<“\n n=“<<n;
cin>>n; cout<<“\n n=“<<Base::n;
} }
}; };
class Derived: public Base{ int main(){
protected: Derived D1;
int n; D1.input();
public: D1.display();
}
Member function overriding
void input(){
class Base{
cout<<“\n Enter a value in
protected:
Derived:”;
int n;
cin>>n;
public:
}
void input(){
void display(){
cout<<“\n Enter a value in
cout<<“\n n=“<<n;
Base:”;
cout<<“\n n=“<<Base::n;
cin>>n;
}
}
};
};
int main(){
class Derived: public Base{
Derived D1;
protected:
D1.input();
int n;
D1.Base::input();
public:
D1.display();
}
Member function overriding
In case of base class having overloaded
functions or if we overload the function in
derived class, we cannot access them from void input(int c, int d){
derived class as they are hidden. So, we have to n=c;
invoke them
class Base{as before. m=d;
protected: }
int n; void display(){
public: cout<<“\n n=“<<n;
void input(){ cout<<“\n m=“<<m;
cout<<“\n Enter a value in cout<<“\n n=“<<Base::n;
Base:”; }
cin>>n; };
} int main(){
void input(int a){ Derived D1;
n=a; D1.input(10,20); //ok
} D1.input() //error
}; D1.input(5) //error
class Derived: public Base{ D1.Base::input(); //ok
protected: D1.Base::input(5); //ok
int m,n; D1.display();
public: }
Forms of Inheritance
A class can be derived in various ways which are listed as follows:
1. Single Inheritance
2. Multiple Inheritance
3. Hierarchical Inheritance
4. Multilevel Inheritance
5. Hybrid Inheritance
1. Single Inheritance:
When a subclass inherits from only one base class, it is known as single inheritance.
Syntax: class DerivedClassName: visibilityMode BaseClassName{
//members
}
B Base Class
D Derived Class
Forms of Inheritance
2. Multiple Inheritance:
When a subclass inherits from multiple base class, it is known as multiple inheritance.
Syntax: class DerivedClassName: visibilityMode Base1, visibilityMode Base2, [,
visibilityMode BaseN]{
//members
}
B1 B2 Base Class
D Derived Class
D1 D2 Derived Class
Forms of Inheritance
4. Multilevel Inheritance:
When a subclass inherits from a class which itself inherits from another class, it is known as
multilevel inheritance.
Syntax: class DerivedClassName1: visibilityMode Base{
//members
}
class DerivedClassName2: visibilityMode DerivedClassName1{
//members
}
B Base Class to D1
D1 Derived Class of B
Base Class to D2
D2 Derived Class of D2
Forms of Inheritance
5. Hybrid Inheritance:
When a subclass inherits from multiple base class and all of its base class inherit from a
single base class, it is known as hybrid inheritance.
B1
B1 B2
D
D1 D2
D1 D2
D3
Multipath Inheritance and virtual base
class
When a base class is derived to two or more than two derived class and the derived classes
are again inherited to the another class, the main base class is inherited from two different
paths which is known as multipath inheritance.
In such cases, the grandchild gets two copy of the main base class. To prevent it, we cant
inherit the class as virtual.
B1
D1 D2
D3
Constructor and Destructor invocation in
Inheritance
When we inherit a class, the constructor of the base class is called and after that the
constructor of derived class.
Similarly, destructor of derived class is called before base class. It is due to the fact the base
class’s members need to be defined before the derived as the base class are inherited.
class Base{ ~Derived(){
public: cout<<“\n Derived Destructor”;
Base(){ }
cout<<“\n Base Constructor”; };
}
~Base(){ int main(){
cout<<“\n Base Destructor”; Derived D1;
} }
};
class Derived: public Base{
public: OUTPUT:
Derived(){ Base Constructor
cout<<“\n Derived Derived Constructor
Constructor”; Derived Destructor
} Base Destructor
Constructor and Destructor invocation in
Inheritance
If we want to pass arguments to base class, we use initialization list.
class Base{
protected:
int x;
public:
Base(int a){
x=a;
} int main(){
}; Derived D1;
class Derived: public Base{ }
public:
Derived():Base(10)
{
cout<<“\n Derived
Constructor”;
}
};
Constructor and Destructor invocation in
Inheritance
Normally, we pass the argument from main function as follows:
class Base{
protected:
int x;
public:
Base(int a){
x=a;
}
}; int main(){
class Derived: public Base{ Derived D1(10,5);
int y; }
public:
Derived(int a, int b):Base(a)
{
y=b;
}
};
Constructor and Destructor invocation in
Inheritance
In case of multiple constructors in the base class, the constructor defined will be called.
class X{
protected:
int x;
public:
X(int a){
x=a;
}
}; int main(){
class Y{ Y obj(1,2);
X obj1; }
int y;
public:
Y(int a, int b): obj1(a)
{
y=b;
}
};
Polymorphism and Dynamic Binding
Function Operator
Overloading Overloading Virtual Function
Pointer to Derived Class
We can normally create pointer to both base class an derived class as needed.
Eg:
Base *bptr,bobj;
bptr=&bobj;
Similarly we can create pointer to derived class as well, but also we can use the pointer to
base class to point to an object of derived class. It is because the derived class contains all
the contents of the base class. Note that since the base class pointer only knows of the
members of the base class, if we assign an object of derived class to it, we can still only use
the members of base class which is inherited.
Also, the vice-versa doesn’t exits, meaning we cant assign a pointer of derived class to
object of base class.
Base Object
Base Pointer
Derived
Object
Derived Derived
Pointer Object
Pointer to Derived Class
Here, type specifies the target type of the cast and the object being cast to the new type.
The reinterpret_cast converts the object fro one type to another type without checking the bit
pattern or size of source and destination type.
int main(){
int a=10;
float *d=reinterpret_cast<float
OUTPUT:
*>(a);
int f= reinterpret_cast<int>(d);
0xa 10 10
cout<<d<< “ “<<f<< “ “<<a;
return 0;
}
Run-Time Type
Information
In run-time polymorphism, we learnt that the type of pointer can vary based on the object it
is holding at run-time. There may arise situations where we need to change the type or even
find out the type of the pointers. At such case, we can use the following operators which are
termed as Run-Time Type Information.
1. dynamic_cast operator
The dynamic_cast operator performs a run time cast along with verifying the validity of a
cast. If the cast is invalid at runtime, then the cast fails by returning NULL.
Syntax:
dynamic_cast<type>(expr)
Casting from derived class to base class is called upcast. In C++, a derived class pointer can
be assigned to base class pointer due to inheritance and it is done implicitly.
Casting from base class to derived class is called downcast. The base class pointer can have
the address of derived class object, then this address of derived class can be assigned to
derived class pointer. This is done using dynamic_cast operator.
For dynamic_cast to work, base class should be polymorphic, i.e. it must have at least one
virtual function.
Run-Time Type
Information
class Base{
public:
virtual void display(){
cout<<“\nBase Class”; int main(){
} check(new Base());
}; check(new Derived());
class Derived: public Base{ }
public:
void display(){
cout<<“\nDerived
Class”;
}
};
void check(Base *b){ Output:
Derived *d; Base Class
if(d=dynamic_cast<Derived Derived Class
*>(b)){
d->display();
}
else{
b->display();
}
Run-Time Type
Information
2. typeid operator
This is used to get the type of the object or variable during runtime.
To use this, we need to include <typeinfo> header file.
It returns an object of class type_info with the following public members:
bool operator ==(const type_info &obj)
bool operator !=(const type_info &obj)
bool before(const type_info &obj)
const char *name()
Syntax:
typeid(object);
Run-Time Type
Information
class temp1{ };
class temp2{ };
int main(){
int a;
char *name;
temp1 t1;
temp2 t2;
OUTPUT:
cout<<“\nType of a is
Type of a is int
“<<typeid(a).name();
Type of name is char *
cout<<“\nType of name is
Type of a is class temp1
“<<typeid(name).name();
Type of a is class temp2
cout<<“\nType of t1 is
Different type of t1 and t2
“<<typeid(t1).name();
cout<<“\nType of t2 is
“<<typeid(t2).name();
if( typeid(t1) !=typeid(t2)){
cout<<“\nDifferent type of t1 and t2”;
}
}
Stream Computation for Console and File Input
Output
ios
istream ostream
streambuf
iostream
getline()
The getline() is different than normal “>>” because it doesn’t discard any whitespaces just
like the get() function.
istream& getline(char *str, Stringsize S, char delim=‘\n’)
int main(){
char name[20];
OUTPUT:
char Address[50];
Enter name of student: Ram Thapa
cout<<“\nEnter name of student:”;
Enter the address: Sanepa
cin.getline(name,20);
Lalitpur
cout<<“\nEnter the address:”;
Nepal$
cin.getline(Address,50,’$’);
Name: Ram Thapa
cout<<“\nName:”<<name;
Address: Sanepa
cout<<“\nAddress:”<<Address;
Lalitpur
return 0;
Nepal
}
Unformatted I/O
write()
Just like getline(), to display an entire line, we have a write function.
ostream& write(char *s, Streamsize size);
The first argument, s , is the string to display and the size is the number of characters to
show which is always less than or equal to size of string.
int main(){
char name[50];
cout<<“\n Enter the name:”; OUTPUT:
cin>>name; Enter the name: Ramesh
cout<<“\nDisplaying in triangular Displaying in triangular format:
format:\n”; R
int length=strlen(name); Ra
for(int i=1;i<=length;i++){ Ram
cout.write(name,i); Rame
cout<<“\n”; Rames
} Ramesh
return 0;
}
Formatted I/O
b. fill()
It is used to fill the empty spaces which is filled with white spaces by default.
Syntax:
cout.fill(ch);
where ch is some characted
Example:
cout.width(5);
cout.fill(‘*’); * * 1 0 7
cout<<107;
This function fill remains unchanged until we change it.
c. precision()
By default, floating numbers are shown with six digit after decimal point. We can change it
as:
cout.precision(d);
where d is the number of digits to the right of decimal point.
Example:
cout.precision(3);
cout<<10.200124
OUTPUT: 10.2
This setting also is saved unless changed.
Formatted I/O
d. setf():
We know that width() displays value from right but what if we need to display from left. For
such and may others, we can set flags as:
cout.setf(arg1,arg2);
The arg1 is one of the formatting flags defined in the ios class and arg2 is known as bit flag
which is used to specify the group to which the formatting flag belongs.
Example:
cout.width(12);
cout.precision(3); * * 1 . 0 3 0 e + 0 0 1
cout.fill(*);
cout.setf(ios::internal,ios::adjustfield);
cout.setf(ios::scientific,ios::floatfield);
cout<<10.298235
Following are some flags that don’t have bit flags:
2. Standard Manipulators:
The header file iomanip provides a set of manipulators which has already been discussed
before:
There are two types of manipulators: Parameterized manipulator and Non-parameterized
manipulator
Parameterized: setw(), setprecision()
Non-parameterized: endl
The difference between manipulator and ios function is that manipulators can be cascaded in
a single line but ios function cannot. Also, ios functions can be called once to have its effect
throughout the program while manipulators cannot.
eg:
Manipulator Equivalent
cout<<setfill(‘*’)<<setw(10)<<123123;
setw(int w) width()
setprecision(int d) precision()
setfill(char ch) fill()
setiosflags(long f) setf()
resetiosflags(long f) unsetf()
endl \n
Formatted I/O
ios
fstreambas
e
File Stream Class
Hierarchy
filebuf: It sets the file buffers to read and write. It contains close() and open() member functions
in it. It is derived from streambuf and is internally used by file stream classes for buffer
management.
fstreambase: This is the base class for fstream, ifstream and ofstream. It also has open() and
close() functions.
ifstream: It provides input operations for file. It inherits the functions get(), getline(), read() and
functions supporting random access like seekg() and tellg() from istream class defined inside
iostream.h
ofstream: It provides output operations. It inherits put() and write() functions along with
functions supporting random access (seekp() and tellp()) from ostream class defined inside
iostream.h
fstream: It is an input-output file stream class. It provides support for simultaneous input and
output operations. It contains open() with default input mode. It inherits all the functions from
istream and ostream classes through iostream class defined inside iostream.h
Opening and Closing
files
In C++, to open a file, we need to obtain a stream. There are three types of streams: input,
output and input/output using ifstream, ofstream and fstream classes.
There are two ways of opening files:
a. Using the constructor function of stream class
b. Using the function open()
The first method is preferred when a single file is used with stream, however, for managing
multiple files with the same stream, the second method is preferred.
ofstream fout(“’Student”);
fout<<name<<“\n”<<roll;
fout.close();
Opening and Closing
files
b. Opening files using open() function:
If we want to open more than one file using the same object, we use open() function.
ifstream fin;
fin.open(“SomeFile”);
fin.close();
fin.open(“SomeOtherFile”);
#include<iostream> strcpy(name,” “);
#include<fstream> roll=0;
using namespace std;
int main(){ ifstream fin;
char name[20]; fin.open(“Student”);
int roll; fin>>name>>roll;
cout<<“\nEnter the name of
student:”; cout<<“\nName:”<<name;
cin>>name; cout<<“\nRoll:”<<roll;
cout<<“\nEnter the roll of student:”; return 0;
cin>>roll; }
ofstream fout;
fout.open(“’Student”);
fout<<name<<“\n”<<roll;
fout.close();
Opening and Closing
files
File Modes:
Normally, the files are opened in default mode, i.e. ifstream for read and ofstream for write.
We can change the modes by specifying a second parameter to the open() function as:
stream_object.open(“filename”,filemode);
The available file modes are as follows:
ios::in : This mode allows you to open a file for reading only.
ios::out : This mode allows you to open a file for writing only. It also opens the file in ios::trunc
mode which means the file is truncated on open, meaning all previous contents will be
discarded.
ios::ate : This seeks to end-of-file upon opening the file. The input and output operation can be
performed anywhere wihin the file.
ios::app: This causes all output to be appended to the end of the file. This is used only with file
where only write operation is performed. This is similar to ios::ate but ios::ate can move the
pointer anywhere in the file but it doesn’t.
ios::trunc: This causes the contents of the pre-existing file by same name to be flushed and
truncates the file to zero length.
ios::nocreate : This causes the open() method to fail if the file doesn’t already exist.
ios::binary : This causes a file to be opened in binary mode. By default, all files are opened in
text mode.
ofstream fout(“’Student”);
fout<<name<<“\n”<<roll;
fout.close();
Read and Write from
file
b. get() and put() function
#include<iostream>
#include<fstream> fout.close();
using namespace std; cout<<“\nTeacher name is:”;
int main(){ ifstream fin;
char ch; fin.open(“Teacher”,ios::in);
cout<<“\nEnter the name of if(!fin){
teacher:”; cout<<\nFile cannot be
ofstream fout; opened”;
fout.open(“Teacher”,ios::app); return 1;
if(!fout){ }
cout<<“\n File cannot be while(1){
opened”; fin.get(ch);
return 1; if(fin.eof()){
} break;
while(1){ }
cin.get(ch); cout.put(ch);
if(ch==“\n”){ }
break; fin.close();
} return 0;
fout.put(ch); }
Read and Write from
file
c. read() and write() function
These functions are used for binary files.
Syntax:
streamObj.write((char *) &variable, sizeof(variable));
streamObj.read((char *) &variable, sizeof(variable));
class Student{
int main(){
char name[20];
fstream file;
int roll;
file.open(“student”,ios::app|ios::out|
char address[20];
ios::binary);
public:
Student s;
void input(){
s.input();
cout<<“\nEnter name, roll and
file.write((char *)&s, sizeof(s));
address”;
file.close();
cin>>name>>roll>>address;
}
file.open(“student”,ios::in|ios::binary);
void display(){
while(file.read((char *)&s, sizeof(s)){
cout<<“\nName:”<<name;
s.display();
cout<<“\nRoll:”<<roll; cout<<“\
}
nAddress:”<<address;
file.close();
}
}
};
File Access Pointer and their
Manipulators
C++ allows us to access file sequentially as well as randomly. To access in random, we use
seekg() , seekp(), tellg() and tellp() to get the pointer location and set it during file operation.
tellg() and tellp()
The tellg() function is used for ifstream and tellp() for ofstream. If both are used for fstream,
both returns same value.
These pointers return the position of get_pointer and put_pointer in terms of byte number
from output and input file respectively.
Prototypes:
long tellg();
long tellp();
Example:
int position_read=fin.tellg();
int position_write=fout.tellp();
seekg() and seekp()
The seekg() function is used for ifstream and seekp() for ofstream.
These pointers sets the get_pointer during reading and put_pointer during writing.
Prototypes:
istream& seekg(long);
ostream& seekp(long);
fout.seekp(-40, ios::end); //will move put_pointer to 40 byte back from end of file
fout.seekp(20, ios::cur);
Testing error during file operations
We have several functions to check for error during file operations:
a. eof()
This function returns non-zero (true) value if end of file is encountered during reading
otherwise zero is returned.
while(1){
//read operation
if(fin.eof()){
//stop reading
}
}
b. bad()
This function returns non-zero (true) value if invalid operation is attempted or any
unrecovered error has occurred such as disk space is full or using to read content of file using
stream object not connected to file.
ofstream fout;
fout.open(“somefile”);
if(fout.bad()){
//show error
}
Testing error during file operations
c. fail()
This function returns non-zero (true) value if input or output operation has failed.
fout.write((char *) &s, sizeof(s));
if(fout.fail()){
//file not opened
}
d. good()
This function returns non-zero (true) value if no error has occur and read and write can be
performed to a file
ofstream fout;
fout.open(“somefile”);
if(fout.good()){
// no error has occured
}
e. We can check error by checking stream class object is null. If null, error has occurred.
ifstream fin;
fin.open(“somefile”);
if(!fin){
// file doesn’t exist for reading
}
Templates
Function
Template
Function overloading allows us to define multiple functions with same name but different
arguments. Normally, if the body is same but the type of argument is different, we use
function overloading. In such cases, we can use template instead.
The general form is:
template<class T>
return_type function_name(T type arguments){
//body
}
Example:
template<class T>
T abs(T n){
return (n<0)? –n : n;
}
Now this function abs() can be called with any type
abs(10.5);
abs(5);
Function
Template
Creating template doesn’t necessarily create all versions of the function. When the function
call is encountered, complier creates a version of the data type on function call. If similar
function call exists, compiler creates a single version only.
template<class T1>
T1 largest(T1 *a,int size){
T1 L=a[0];
for(int i=1;i<size;i++){
if(L<a[i]){
L=a[i];
}
}
return L;
}
int main(){
int a[]={1,5,7,10,2,3};
cout<<“\n Largest element in Integer
Array:”<<largest(a,6);
float b[]={10.25,25.36,22.3,12.56};
cout<<“\nLargest element is float
array:”<<largest(b,4);
}
Function Template with Multiple
Argument
We can use more than one generic type while defining functions as:
template<class T1,class T2….> template<class T1, class T2>
returnType functionName(arguments of T1,T2,….){ void cal(T1 p[], int size, T2 &sum, T2
//body of function &av){
} for(int i=0;i<size; i++){
sum+=p[i];
av=sum/size;
}
}
int main(){
OUTPUT: int n[]={1,2,3,4,5};
Sum:15 Average:3 float sum=0.0, avg=0.0;
Sum:52.64 Average:13.16 cal(n,5,sum,avg);
cout<<“\n Sum:”<<sum<<“\t
Average:”<<avg;
float a[]={1.12, 10.25, 36.25, 5.02};
double sa=0.0, av=0.0;
cal(a,4,sa,av);
cout<<“\n Sum:”<<sa<<“\t
Average:”<<av;
}
Overloading of template
function
There may arise situations where we need to overload as well as create templates. We can
overload in two ways:
a. Overloading of function template with normal functions
b. Overloading of function template with other templates
int main(){
template<class T>
mini(10,20);
void mini(T a, T b){
mini(10.25,20.25);
cout<<“\nTemplate function”;
return 0;
if(a<b)
}
cout<<a;
else
cout<<b;
}
void mini(int a, int b){
cout<<“\nInteger function”; OUTPUT:
if(a<b) Integer Function: 10
cout<<a; Template Function: 10.25
else
cout<<b;
}
Overloading of template
function
In above example, the error with the second function call can be removed with the following
line:
mini<double>(10,20.25);
This tells the compiler to use double as the data type in the template.
The choosing of the overloaded function is done in the following steps:
a. Call an ordinary function that has an exact match.
b. Call a template function that could be created with an exact match.
c. Try normal overloading resolution to normal functions and call the one that matches.
An error is generated if no match is found.
Overloading of template
function
b. Overloading of function template with other templates
We can create multiple function templates with same name and the function which is most
specialized or matching
template<class T> will be called.
void mini(T a, T b){ int main(){
cout<<“\nTwo argument Template mini(10,20);
function”; //mini(10,20.25); no match found (int,
if(a<b) double);
cout<<a; mini(30,20,50);
else }
cout<<b;
}
template<class T>
void mini(T a, T b, T c){
cout<<“\nThree argument Template
function”; OUTPUT:
if(a<b && a<c) Two argument Template Function: 10
cout<<a; Three argument Template Function : 20
else if(b<a && b<c)
cout<<b;
else
cout<<c;
Class Template
Just like with functions, if different classes have same functionality for different data types,
class template can be defined.
General Form:
template<class T>
class className{
//members
};
We can then declare the objects of the class as:
className<type>objectName(argList);
Example:
template<class T>
class Array{
T a[10];
public:
void input();
};
We can then define the object as:
Array<int> obj1;
Array<float> obj2;
Defining member functions of class
template
If the functions are defined outside the template class body, they should always be defined
with the full template function. template<class T1>
template<class T1> T1 Array<T1>::Largest(){
returnType className<T1>::functionName(args){ T1 L=a[0];
//body for(int i=0;i<size;i++){
} template<class T> if(a[i]>L)
class Array{ L=a[i];
T *a; }
int size; return L;
public: }
Array(T *n,int s){ int main(){
a=new T[s]; int temp[]={1,5,8,10,3};
for(int i=0;i<s;i++){ Array<int>Obj1(temp,5);
a[i]=n[i]; cout<<“\nLargest in
} integer:”<<Obj1.Largest();
size=s; double
} test[]={10.25,145.2,52.6,96.354};
T Largest(); Array<double>Obj2(test,4);
}; cout<<“\nLargest in
double:”<<Obj2.Largest();
return 0;
Class Template with multiple
parameters
We can define multiple parameters in template for class as following:
template<class T1, class T2,…>
class className{
//members
};
We can then define the object as following:
classname<type1,type2,…>objectName;
We can then define the member function outside the class as:
template<class T1, class T2,…>
returnType className<T1,T2,…>::functionName(args){
//body of function
}
Class Template with multiple
parameters int main(){
template<class T1,class T2,class T3> Record<int,char,double>
class Record{ R1(10,’R’,1045.12);
T1 a; Record<double,char,int>
T2 b; R1(20.1245,’S’,12);
T3 c; R1.show();
public: R2.show();
Record(T1 x, T2 y, T3 z){ return 0;
a=x; }
b=y;
c=z;
}
void show(); OUTPUT:
}; 10 R 1045.12
template<class T1,class T2,class T3> 20.1245 S 12
void Record<T1,T2,T3>::show(){
cout<<endl<<a<<“ “<<b<<“ “<<c;
}
Non-Type Template Arguments
A non-type template argument provided within a template argument list is an expression
whose value can be determined at compile time. Such arguments must be constant
expressions, addresses of functions or objects with external linkage, or addresses of static
class members.
Non-type template arguments are normally used to initialize a class or to specify the sizes of
class members.
General Form is:
template<class T, int size>
class array{
T a[size];
….
};
The object can then be defined as following:
Stack<double,20> obj1;
Stack<double,10+10>obj2;
template<class T>
class Base{
protected:
T a;
public:
void display(){
Base(T x){
Base<int>::display();
a=x;
cout<<endl<<b;
}
}
void display(){
};
cout<<endl<<a;
int main(){
}
Derived d(1,2);
};
d.display();
class Derived: public Base<int>{
}
int b;
public:
Derived(int x, int y):Base<int>(x){
b=y;
}
Derived Class Template
We can also define base class as template as:
template<class T>
class Base{
protected:
T a;
public:
Base(T x){ void display(){
a=x; Base<int>::display();
} cout<<endl<<b;
void display(){ }
cout<<endl<<a; };
} int main(){
}; Derived<int>d(1,2);
template<class T> d.display();
class Derived: public Base<int>{ }
T b;
public:
Derived(int x, T y):Base<int>(x){
b=y;
}
Derived Class Template
Also, we can get the template of both base and derived as:
template<class T>
class Base{
protected:
T a;
public:
Base(T x){ void display(){
a=x; Base<T1>::display();
} cout<<endl<<b;
void display(){ }
cout<<endl<<a; };
} int main(){
}; Derived<float,int> d(1,2);
template<class T1,class T> d.display();
class Derived: public Base<T1>{ }
T b;
public:
Derived(T1 x, T y):Base<T1>(x){
b=y;
}
Derived Class Template
Also, we can get the template only derived as:
class Base{
protected:
int a;
public:
Base(int x){
void display(){
a=x;
Base::display();
}
cout<<endl<<b;
void display(){
}
cout<<endl<<a;
};
}
int main(){
};
Derived<int> d(1,2);
template<class T>
d.display();
class Derived: public Base {
}
T b;
public:
Derived(int x, T y):Base(x){
b=y;
}
Standard Template Library
STL is a feature in C++ which includes a lot of general purpose, templatized class and
functions that implement many popular and commonly used algorithms and data structures.
It has three major components:
a. Containers
b. Algorithms
c. Iterators
Algorithm Algorithm
1 Container Iterator 2 2
Iterator 1
Object 1
Object 3 Object 2
Iterator 3
Algorithm
3
Standard Template Library
a. Containers:
Containers are objects that hold other objects. It is a way data is organized in memory. The
STL defines ten containers that are grouped into three categories:
a. Sequence container –Vector,List,Deque
b. Associative container – set, multiset, map, multimap
c. Derived container - stack, queue, priority_queue
b. Algorithm:
An algorithm is a procedure that is used to process the data in containers. STL provides sixty
standard algorithms to support more extended or complex operations.
Algorithms arenot part of container class so that the same algorithm can be used for various
containers.
They are categorized as:
a. Mutating algorithms
b. Sorting algorithm
c. Set algorithm
d. Relational algorithm
e. Retrieve or non-mutating algorithm
c. Iterators:
Iterator behaves like a pointer and are used to access individual elements of a container.
They are used to traverse from element to element in a container, known as iterating.
Types: input, output, forward, bidirectional, random
Exception Handling
catch(Derived1 c){
cout<<“\nDerived1
void test(int b){ Exception”;
cout<<“\n Inside function”; }
try{ catch(Derived2 c){
if(b==0) cout<<“\nDerived2
throw Base(); Exception”;
if(b==1) }
throw Derived1(); catch(Base c){
if(b==2) cout<<“\nBase class
throw Derived2(); Exception”;
} }
cout<<“\nEnd of function”;
}
Rethrowing an
exception
If an exception occurs, there may be times when the exception doesn’t have a matching
catch block or handlers. In such case, we can rethrow the exception to another block and
handle it there.
It can be done by using throw statement without any arguments.
int main(){
Stack obj;
try{
obj.push(1);
obj.push(2);
obj.push(3);
//obj.push(4); OUTPUT:
obj.pop(); Popped Element:3
obj.pop(); Popped Element:2
obj.pop(); Popped Element:1
obj.pop(); Exception: Stack Empty
}
catch(Stack::out_Of_Range Range){
cout<<“\
nException:”<<Range.message;
}
}
Specifying exception
Throwing or catching an exception affects the way a function relates to other functions. It
can be therefore worthwhile to specify the set of exceptions that might be thrown as part
of the function declaration.
To restrict a function to throw only certain specified exceptions, we do this by adding a
throw list clause to the function definition. int main(){
General form: int x,y;
returnType function(args) throw (type-list){ try{
//body Calculate(20,0);
} Calculate(10,1);
If the function throws any other type of exception which is not listed,
}
it will cause an abnormal termination. catch(int c){
void Calculate(int a, int b)
cout<<“\nInteger
throw(int,double){
Exception”;
cout<<“\n Inside function:”;
}
if(b==0)
catch(double c){
throw b;
cout<<“\nDouble
if(b==1)
Exception”;
throw 1.0;
}
cout<<“\n Quotion is:”<<a/b
cout<<“\nEnd of Program”;
}
}
Handling uncaught
exception
terminate() function is called when an exception is thrown but not caught.
Also, it is called when program tries to rethrow an exception but no exception is thrown
beforehand.
terminate() function calls abort() by default and program stops. We can change the
behavior of this function using set_terminate() function as:
terminate_handler set_terminate(terminate_handler newHandler);
The terminate handler should be a function which take no argument and do not have a
return type. It must stop the program execution and must not return to the program or
resume it in any way.
Handling uncaught
exception
void test_handler(){
cout<<“\nInside test handler:”;
}
int main(){
set_terminate(test_handler); OUTPUT:
try{ Inside try block
cout<<“\nInside try block”; Inside test handler
throw 10; **Program terminates
} abnormally**
catch(char ch){
cout<<“\nCharacter Exception”;
}
return 0;
}
Handling unexpected
exception
Similarly to uncaught exception, the system throws an error when exception is thrown
which is not in the exception throw list. It invokes unexpected() function.
By default unexpected() calls terminate(), but we can change the function that is called by
unexpected().
General form:
void test_handler(){
unexpected_handler set_unexpected(unexpected_handler newHandler);
cout<<“\nInside test handler:”;
} catch(int c){
void Calculate(int a, int b) throw (int) cout<<“\nInteger
{ Exception”;
cout<<“\nInside function”; }
if(b==0) cout<<“\nEnd of Program”;
throw ‘A’; }
cout<<“\nQuotion is:”<<a/b;
}
int main(){ OUTPUT:
set_unexpected(test_handler); Inside function
int x,y; Inside test handler
try{ **Program terminates
Calculate(10,0); abnormally**
}