(Combined) Mahbub Sir Lecture
(Combined) Mahbub Sir Lecture
(Combined) Mahbub Sir Lecture
Lect-01
Basic Program Construction
Functions
Functions are one of the fundamental building blocks of C++. The FIRST
program consists almost entirely of a single function called main(). The
only parts of this program that are not part of the function are the first two
lines—the ones that start with #include and using.
The parentheses following the word main are the distinguishing feature of a
function. Without the parentheses the compiler would think that main refers to a
variable or to some other pro- gram element.
Always Start with main()
}
Variable Type Summary
unsigned Data Types
By eliminating the sign of the character and integer
types, you can change their range to start at 0 and
include only positive numbers. This allows them to
represent numbers twice as big as the signed type.
Lecture 2
Reminder
⚫ Library file has to discuss later
⚫ Procedural and object oriented programming
have to discuss later
Complex number
#include<iostream>
#include<cmath>
#include<complex>
using namespace std;
int main(){
float x,y;
complex<float>c1,c2,c;
c1=complex<float> (2.0,4.0);
cout<<"Enter the real and imaginary parts of a complex
number\n";
cin>>x>>y;
c2=complex<float>(x,y);
c=c1+c2;
cout<<"Summation of complex number is"<< c;
return 0;}
Output of the above code
Enter the real and imaginary parts of a complex number
24
Summation of complex number is(4,8)
Operation of complex variable
⚫ If we add the following code
float x1=real(c);
float x2=imag(c);
cout<<"The real part of the complex sum is"<<x1<<"\n";
cout<<"The imaginary part of the complex sum is"<<x2<<"\n";
Output
Enter the real and imaginary parts of a complex number 29 8
Summation of complex number is(31,12)
The real part of the complex sum is31
The imaginary part of the complex sum is12
cout<<"Absolute value is:" << abs(c)<<"\n";
cout<<"Phase angle is:" << arg(c) <<"\n";
Output:
Absolute value is:13.9284
Phase angle is:1.20362
cout << "Norm value is:"<< norm(c) <<"\n";
cout << "Complex conguate is:" << conj(c) <<"\n";
Output:
Norm value is:194
Complex conguate is:(5,-13)
cout <<"Square root is: "<< sqrt(c) << "\n";
cout << " 3rd power of complex number is :"<<pow(c,3) <<"\n";
Output:
Square root is: (3,2)
3rd power of complex number is :(-2035,-828)
Exponential of complex number is :(125.239,-79.6345)
Log of complex number is :(2.56495,1.17601)
Complex variable operation
⚫ Trigonometric and hyperbolic function of
complex variable ---self studys
Logical variable
⚫ Boolean variable studied as bool variable
Relational Operators
In C++ Programming, the values stored in two
variables can be compared using following
operators and relation between them can be
determined.
⚫ Various C++ relational operators available are-
⚫ Operator, Meaning
⚫ > ,Greater than
⚫ >= , Greater than or equal to
⚫ == , Is equal to
⚫ != , Is not equal to
⚫ < , Less than or equal to <=
Now if the result after comparison of two
variables is True, then if statement returns value
1.
struct Room {
struct Distance
{
Distance length;
int feet;
Distance width;
}
float inches;
Room dining;
dining.length.feet = 13;
dining.length.inches = 6.5;
dining.width.feet = 10;
dining.width.inches = 0.0;
Initialize nested structure
day1 = Mon;
day2 = Thu;
int diff = day2 - day1;
Example of Enumeration
enum months { Jan, Feb, Mar, Apr, May, Jun, Jul,
Aug, Sep, Oct, Nov, Dec };
enum switch { off, on };
enum meridian { am, pm };
enum chess { pawn, knight, bishop, rook, queen,
king };
enum coins { penny, nickel, dime, quarter, half-
dollar, dollar };
Functions
A function groups a number of program
statements into a unit and gives it a name. This
unit can then be invoked from other parts of the
program.
The most important reason to use functions is to
aid in the conceptual organization of a program.
Another reason to use functions (and the reason
they were invented, long ago) is to reduce
program size. Any sequence of instructions that
appears in a program more than once is a
candidate for being made into a function. The
function’s code is stored in only one place in
memory, even though the function is executed
many times in the course of the program.
#include <iostream> void starline()
using namespace std;
void starline();
int main() { {
for(int j=0; j<45;
starline(); j++)
cout << “Data type Range cout << ‘*’;
\n”; cout << endl;
starline(); }
return 0;
}
Eliminating the declaration
#include <iostream>
using namespace std; int main() {
void starline()
starline();
{ cout << “Data type
for(int j=0; j<45; j++) Range \n”;
cout << ‘*’; starline();
cout << endl; return 0;
} }
Passing arguments
#include <iostream>
using namespace std; void starline(char ch, int n)
void starline(char, int);
int main() { {
for(int j=0; j<n; j++)
starline(‘-’,45); cout << ch;
cout << “Data type Range cout << endl;
\n”; }
starline(‘=’, 45);
return 0;
}
Passing variables
#include <iostream>
void starline(char ch, int n)
using namespace std;
void starline(char, int);
{
int main() {
for(int j=0; j<n; j++)
Char chin; int nin
cout << ch;
cin>> chin;
cout << endl;
cin >>nin
}
starline(chin,nin);
return 0;
}
Passing structure argument
#include <iostream>
using namespace std;
struct Distance {
int feet;
float inches;
};
void engldisp( Distance );
int main() {
Distance d1, d2; //define two lengths
cout << “Enter feet: “; cin >> d1.feet;
cout << “Enter inches: “; cin >> d1.inches;
cout << “\nEnter feet: “; cin >> d2.feet;
cout << “Enter inches: “; cin >> d2.inches;
cout << “\nd1 = “;
engldisp(d1);
cout << “\nd2 = “;
engldisp(d2);
cout << endl;
return 0;
}
void engldisp( Distance dd )
{
cout << dd.feet << “\’-” << dd.inches << “\””;
}
Output
Enter feet: 6
Enter inches: 4
Enter feet: 5
Enter inches: 4.25
Functions
Lect-04
Returning Values from Functions
#include <iostream> float lbstokg(float pounds)
using namespace std; {
float lbstokg(float); float kilograms = 0.453592 * pounds;
int main() return kilograms;
{ }
float lbs, kgs;
cout << “\nEnter your
Enter your weight in pounds: 182
weight in pounds: “;
Your weight in kilograms is 82.553741
cin >> lbs;
kgs = lbstokg(lbs);
cout << “Your weight in
kilograms is “ << kgs <<
endl;
return 0;
}
Returning Structure Variables
#include <iostream>
using namespace std;
struct Distance
cout << “Enter feet: “;cin >>d2.feet;
{
cout << “Enter inches: “; cin >>d2.inches;
int feet;
d3 = addengl(d1, d2);
float inches;
cout << endl;
};
engldisp(d1); cout << “ + “;
Distance addengl(Distance,
engldisp(d2); cout << “ = “;
Distance);
engldisp(d3); cout << endl;
void engldisp(Distance);
return 0;
int main()
}
{
Distance d1, d2, d3;
cout << “\nEnter feet: “;cin
>>d1.feet;
cout << “Enter inches: “; cin
>>d1.inches;
void engldisp( Distance dd )
Distance addengl( Distance dd1, Distance
{
dd2 )
cout << dd.feet << “\’-” <<
{
dd.inches << “\””;
Distance dd3;
}
dd3.inches = dd1.inches + dd2.inches;
dd3.feet = 0;
if(dd3.inches >= 12.0) Enter feet: 4
{ Enter inches: 5.5
dd3.inches -= 12.0; Enter feet: 5
dd3.feet++; Enter inches: 6.5
} 4’-5.5” + 5’-6.5” = 10’-0”
dd3.feet += dd1.feet + dd2.feet;
return dd3;
}
#include <iostream>
using namespace std; void intfrac(float n, float&
void intfrac(float, float&, float&); intp, float& fracp)
int main() {
{ long temp =
float number, intpart, fracpart; static_cast<long>(n);
do { //convert to long,
cout << "Enter a real number: "; intp =
//number from user static_cast<float>(temp);
cin >> number; //back to float
intfrac(number, intpart, fracpart); fracp = n - intp;
cout << "Integer part is " << intpart<< ", fraction }
part is " << fracpart << endl; Enter a real number: 99.44
} while( number != 0.0 ); Integer part is 99, fractional
//exit loop on 0.0 part is 0.44
return 0;
}
Different Numbers of Arguments
#include <iostream> void repchar(char ch)
using namespace std; {
void repchar(); for(int j=0; j<45; j++)
void repchar(char); cout << ch;
void repchar(char, int); cout << endl;
}
int main() void repchar(char ch, int n)
{ {
repchar(); for(int j=0; j<n; j++)
repchar(‘=’); cout << ch;
repchar(‘+’, 30); cout << endl;
return 0; }
}
void repchar()
{
Different Kinds of Arguments
#include <iostream> cout << “Enter entire distance in
using namespace std; inches: “; cin >> d2;
struct Distance engldisp(d1);
{ engldisp(d2);
int feet; cout << endl;
float inches; return 0;
}; }
void engldisp( Distance ); void engldisp( Distance dd )
void engldisp( float ); {
int main() cout << dd.feet << “\’-” << dd.inches
{ << “\””;}
Distance d1; void engldisp( float dd )
float d2; {int feet = static_cast<int>(dd / 12);
cout << “\nEnter feet: “; cin >> d1.feet; float inches = dd - feet*12;
cout << “Enter inches: “; cin >> cout << feet << “\’-” << inches <<
d1.inches; “\””;}
Recursion
The existence of functions makes possible a programming technique called
recursion.Recursion involves a function calling itself. This sounds rather
improbable, and indeed a function calling itself is often a bug. However, when
used correctly this technique can be surprisingly powerful.
#include <iostream>
using namespace std; unsigned long factfunc(unsigned long
unsigned long factfunc(unsigned long); n)
int main() {
{ if(n > 1)
int n; return n * factfunc(n-1); //self call
unsigned long fact; else
cout << “Enter an integer: “; return 1;
cin >> n; }
fact = factfunc(n);
cout << “Factorial of “ << n << “ is “ << fact
<< endl;
return 0;
}
Inline Functions: function save memory
We mentioned that functions save memory space because all the calls to the
function cause the same code to be executed; the function body need not be
duplicated in memory. When the compiler sees a function call, it normally
generates a jump to the function. At the end of the function it jumps back to the
instruction following the call
Inline Functions: small function can slow the process
While this sequence of events may save memory space, it takes some extra time.
There must be an instruction for the jump to the function (actually the assembly-
language instruction CALL or something similar), instructions for saving registers,
instructions for pushing arguments onto the stack in the calling program and
removing them from the stack in the function(if there are arguments), instructions
for restoring registers, and an instruction to return to the calling program. The
return value (if any) must also be dealt with. All these instructions slow down the
program.
Inline Functions can save excution time
To save execution time in short functions, you may elect to put the code in the
function body directly inline with the code in the calling program. That is, each time
there’s a function call in the source file, the actual code from the function is
inserted, instead of a jump to the function.
#include <iostream>
using namespace std;
inline float lbstokg(float pounds)
{
return 0.453592 * pounds;
}
int main()
{
float lbs;
cout << “\nEnter your weight in pounds: “;
cin >> lbs;
cout << “Your weight in kilograms is “ << lbstokg(lbs)
<< endl;
return 0;
}
Default Arguments
Surprisingly, a function can be called without specifying all its arguments. This
won’t work on just any function: The function declaration must provide default
values for those arguments that are not specified.
#include <iostream>
using namespace std; void repchar(char ch, int n)
void repchar(char=’*’, int=45); //defaults supplied
int main() {
{ //
repchar(); if necessary
repchar(‘=’); for(int j=0; j<n; j++)
repchar(‘+’, 30); cout << ch;
return 0; cout << endl;
} }
Local Variables
Variables defined within a function body
void somefunc()
are called local variables because they
{
have local scope. However, they are also
int somevar;
sometimes called automatic variables,
float othervar;
because they have the automatic storage
}
class.
A local variable is not created until the function in which it is defined is called.
(More accurately, we can say that variables defined within any block of code are
not created until the block is executed.
The function returns and control is passed back to the calling program, the
variables are destroyed and their values are lost. The name automatic is used
because the variables are automatically created when a function is
called and automatically destroyed when it returns.
The time period between the creation and destruction of a variable is called its
lifetime (or sometimes its duration)
The idea behind limiting the lifetime of variables is to save memory space.
Scope of the variables
A variable’s scope, also called visibility, describes the locations within a program
from which it can be accessed. It can be referred to in statements in some parts of
the program; but in others, attempts to access it lead to an unknown variable error
message. The scope of a variable is that part of the program where the variable is
visible.
void somefunc()
{
int somevar; //local variables
float othervar;
somevar = 10; //ok
othervar = 11; //ok
nextvar = 12; //illegal: not visible in somefunc()
}
void otherfunc()
{
int nextvar; //local variable
somevar = 20; //illegal: not visible in otherfunc()
othervar = 21; //illegal: not visible in otherfunc()
nextvar = 22; //ok
}
Class and object
Lect-5
Class
We’ve learned about structures, which provide a way to
group data elements. We’ve examined functions, which
organize program actions into named entities. In Class, we’ll
put these ideas together to create classes
A Simple Class
#include <iostream> int main()
using namespace std;
{
class smallobj smallobj s1, s2;
{ s1.setdata(1066);
s2.setdata(1776);
private: s1.showdata();
int somedata; s2.showdata();
public: return 0;
void setdata(int d) }
{ somedata = d; } Output:
Data is 1066
void showdata() Data is 1776
{ cout << “Data is “ << somedata << endl;}
private and public
The body of the class contains two unfamiliar keywords: private and public. What
is their purpose?
A key feature of object-oriented programming is data hiding. This term does not
refer to the activities of particularly paranoid programmers; rather it means that
data is concealed within a class so that it cannot be accessed mistakenly by
functions outside the class. The primary mechanism for hiding data is to put it in a
class and make it private. Private data or functions can only be accessed from
within the class. Public data or functions, on the other hand, are accessible from
outside the class.
Constructor
Lect-06
A constructor is a special type of member function that initialises an object
automatically when it is created. Constructor has the same name as that of the class
and it does not have any return type. Also, the constructor is always public.
class temporary
int main()
{
{
private:
Temporary t1;
int x;
... .. ...
float y;
}
public:
// Constructor
{ }
};
Another way of definition
1. Destructors are special member functions of the class required to free the
3. Name of the Destructor should be exactly same as that of name of the class.
4. Destructors does not have any return type. Not even void.
5. The Destructor of class is automatically called when object goes out of scope.
#include<iostream> int main( )
using namespace std; {
class Marks Marks m1;
{ Marks m2;
public: return 0;
int maths; }
int science;
//constructor Inside Constructor
Marks() { C++ Object created
cout << "Inside Constructor"<<endl; Inside Constructor
cout << "C++ Object created"<<endl; C++ Object created
}
//Destructor Inside Destructor
~Marks() { C++ Object destructed
cout << "Inside Destructor"<<endl; Inside Destructor
cout << "C++ Object destructed"<<endl; C++ Object destructed
}
};
Lecture 7
Object as function arguments
In the following example the following concepts will be illustrated:
constructor overloading
}
Object parameter initialization
dist3.add_dist(dist1, dist2);
Besides dist3, the object for which it was called, it can also access dist1 and dist2,
because they are supplied as arguments. You might think of dist3 as a sort of
phantom argument; the member function always has access to it, even though it is
not supplied as an argument. That’s what this statement means: “Execute the
add_dist() member function of dist3.” When the variables feet and inches are
referred to within this function, they refer to dist3.feet and dist3.inches.
The default copy constructor
A no-argument constructor can initialize data members to constant values, and a
multi-argument constructor can initialize data members to values passed as
arguments. Let’s mention another way to initialize an object: you can initialize it
with another object of the same type. Surprisingly, you don’t need to create a
special constructor for this; one is already built into all classes. It’s called the
default copy constructor.
int main() Distance dist2(dist1);
{ And
Distance dist1(11, 6.25); Distance dist3 = dist1;
Distance dist2(dist1); Initialize variable dist2 and
Distance dist3 = dist1; dist3 like dist1
cout << “\ndist1 = “; dist1.showdist();
cout << “\ndist2 = “; dist2.showdist();
cout << “\ndist3 = “; dist3.showdist();
cout << endl;
return 0;
}
Returning Object from Functions
#include <iostream> void getdist()
using namespace std; {
class Distance cout << “\nEnter feet: “; cin >> feet;
Distance class cout << “Enter inches: “; cin >> inches;
{ }
private: void showdist()
int feet; //display distance
float inches; { cout << feet << “\’-” << inches << ‘\”’; }
public: Distance add_dist(Distance);
//constructor (no args) };
Distance() : feet(0), inches(0.0)
{}
//constructor (two args)
Distance(int ft, float in) : feet(ft),
inches(in)
{}
Distance Distance::add_dist(Distance d2)
{
Distance temp;
//temporary variable
temp.inches = inches + d2.inches; //add the inches
if(temp.inches >= 12.0)
{
temp.inches -= 12.0;
//by 12.0 and
temp.feet = 1;
}
temp.feet += feet + d2.feet;
//add the feet
return temp;
}
int main()
{
Distance dist1, dist3;
Distance dist2(11, 6.25);
dist1.getdist();
dist3 = dist1.add_dist(dist2);
cout << “\ndist1 = “;
cout << “\ndist2 = “;
cout << “\ndist3 = “;
cout << endl;
return 0;
}
Structure and Class
you can use structures in almost exactly the same way that you use classes. The
only formal difference between class and struct is that in a class the members are
private by default, while in a structure they are public by default.
Classes, Objects and Memory
Lecture 8
Array of Objects
public:
#include <iostream> void getdist()
using namespace std; //get length from user
class Distance {
//English Distance class cout << “\n
{ Enter feet: “; cin >> feet;
private: cout << “
int feet; Enter inches: “; cin >> inches;
float inches; }
c1=0
c2=0
c1=1
c2=2
How do we teach a normal C++ operator to act on a
user-defined operand?
The keyword operator is used to overload the ++ operator in this declarator: void
operator ++ () The return type (void in this case) comes first, followed by the
keyword operator, followed by the operator itself (++), and finally the argument list
enclosed in parentheses (which are empty here). This declarator syntax tells the
compiler to call this member function whenever the ++ operator is encountered,
provided the operand (the variable operated on by the ++) is of type Counter.
the only way it can distinguish between overloaded operators is by looking at the
data type of their operands. If the operand is a basic type such as an int, as in
++intvar; then the compiler will use its built-in routine to increment an int. But if the
operand is a Counter variable, the compiler will know to use our user-written
operator++() instead.
Lecture 9
Nameless Temporary Objects
There are more convenient ways to return temporary
objects from functions and overloaded
operators. Let’s examine another approach
#include <iostream>
using namespace std; int main()
class Counter {
{ Counter c1, c2; //c1=0, c2=0
private: cout << “\nc1=” << c1.get_count();
unsigned int count; cout << “\nc2=” << c2.get_count();
public: ++c1; //c1=1
Counter() : count(0) no args c2 = ++c1;
{} cout << “\nc1=” << c1.get_count();
Counter(int c) : count(c) { } cout << “\nc2=” << c2.get_count()
unsigned int get_count() << endl;
{ return count; } return 0;
Counter operator ++ () { }
++count;
return Counter(count);
} In this program a single statement
}; return Counter(count);
Overloading Binary Operators
Binary operators can be overloaded just as easily as unary operators. we showed
how two English Distance objects could be added using a member function
add_dist():
dist3.add_dist(dist1, dist2);
You can use member functions in a derived class that override—that is, have the
same name as—those in the base class. You might want to do this so that calls in
your program work the same way for objects of both base and derived classes.
#include <iostream> class Stack2 : public Stack
using namespace std; {
#include <process.h> public:
class Stack void push(int var)
{ {
protected: if(top >= MAX-1)
enum { MAX = 3 }; { cout << “\nError: stack is full”; exit(1); }
int st[MAX]; Stack::push(var); //call push() in Stack class
int top; }
public: int pop() //take number off stack
Stack() {
{ top = -1; } if(top < 0) //error if stack empty
void push(int var) { cout << “\nError: stack is empty\n”; exit(1); }
{ st[++top] = var; } return Stack::pop(); //call pop() in Stack class
int pop() }
{ return st[top--]; } };
};
int main() Output:
{ 33
Stack2 s1; 22
s1.push(11); 11
s1.push(22); Error: stack is empty
s1.push(33);
C objC;
a = objC.privdataA; //error: not accessible
a = objC.protdataA; //error: not accessible
a = objC.pubdataA;
return 0;
}
Multiple Inheritance
#include <iostream> class C: public A, public B {
using namespace std; public:
int c = 20;
class A { C() {
public: cout << "Constructor for
int a = 5; class C" << endl;
A() { cout<<"Class C inherits
cout << "Constructor from class A and class B" <<
for class A" << endl; endl;
} }
}; };
class B {
public:
int b = 10;
B() {
cout << "Constructor
for class B" << endl;
}};
int main() {
C obj; Output:
cout<<"a = "<< obj.a <<endl; Constructor for class A
cout<<"b = "<< obj.b <<endl; Constructor for class B
cout<<"c = "<< obj.c <<endl; Constructor for class C
return 0; Class C inherits from
} class A and class B
a = 5
b = 10
c = 20
Virtual Functions
Virtual means existing in appearance but not in reality. When virtual functions are
used, a program that appears to be calling a function of one class may in reality be
calling a function of a different class.
Normal Member Functions Accessed with Pointers
#include <iostream> int main()
using namespace std; {
class Base Derv1 dv1; //object of derived class 1
{ Derv2 dv2; //object of derived class 2
public: Base* ptr; //pointer to base class
void show(){ cout << “Base\n”; } ptr = &dv1;
}; ptr->show();
class Derv1 : public Base ptr = &dv2;
{ ptr->show();
public: return 0;
void show(){ cout << “Derv1\n”; } }
};
class Derv2 : public Base
{ Output:
Base
public: Base
void show(){ cout << “Derv2\n”; }};
Virtual Member Functions Accessed with Pointers
#include <iostream> int main()
using namespace std; {
class Base Derv1 dv1; //object of derived class 1
{ Derv2 dv2; //object of derived class 2
public: Base* ptr; //pointer to base class
virtual void show(){ cout << “Base\n”; } ptr = &dv1;
}; ptr->show();
class Derv1 : public Base ptr = &dv2;
{ ptr->show();
public: return 0;
void show(){ cout << “Derv1\n”; } }
}; The output of this program is
class Derv2 : public Base Derv1
{ Derv2
public:
void show(){ cout << “Derv2\n”; }};
Polymorphism in C++
The word polymorphism means having many forms. In simple words, we can
form.
Real life example of polymorphism, a person at a same time can have different
same person posses have different behavior in different situations. This is called
polymorphism.
Source: https://www.geeksforgeeks.org/polymorphism-in-c/
Polymorphism is considered as one of the important features of Object
Oriented Programming.
Function templates
Function templates are special functions that can operate with generic types.
This allows us to create a function template whose functionality can be
adapted to more than one type or class without repeating the entire code for
each type.
In C++ this can be achieved using template parameters. A template parameter
is a special kind of parameter that can be used to pass a type as argument: just
like regular function parameters can be used to pass values to a function,
template parameters allow to pass also types to a function. These function
templates can use these parameters as if they were any other regular type.
The format for declaring function templates with type parameters is:
The only difference between both prototypes is the use of either the
keyword class or the keyword typename. Its use is indistinct, since
both expressions have exactly the same meaning and behave exactly
the same way.
For example, to create a template function that returns the
greater one of two objects we could use:
For example, to call GetMax to compare two integer values of type int
we can write:
int x,y;
GetMax <int> (x,y);
When the compiler encounters this call to a template function, it uses the template to
automatically generate a function replacing each appearance of myType by the type
passed as the actual template parameter (int in this case) and then calls it. This
process is automatically performed by the compiler and is invisible to the
programmer.
// function template int main () {
#include <iostream> int i=5, j=6, k;
using namespace std; long l=10, m=5, n;
k=GetMax<int>(i,j);
template <class T> n=GetMax<long>(l,m);
T GetMax (T a, T b) { cout << k << endl;
T result; cout << n << endl;
result = (a>b)? a : b; return 0;
return (result); }
}
We can also define function templates that accept more than one type
parameter, simply by specifying more template parameters between the angle
brackets. For example:
template <class T, class U>
T GetMin (T a, U b) {
return (a<b?a:b);
}
In this case, our function template GetMin() accepts two parameters of
different types and returns an object of the same type as the first parameter
(T) that is passed. For example, after that declaration we could call GetMin()
with:
int i,j;
long l;
i = GetMin<int,long> (j,l);
Using typename (source:https://www.geeksforgeeks.org/templates-cpp/)
C++ adds two new keywords to support templates: ‘template’ and ‘class’. The second keyword can
always be replaced by keyword ‘typename’.
#include <iostream>
using namespace std;
// One function works for all data types. This would work
// even for user defined types if operator '>' is overloaded
template <typename T>
T myMax(T x, T y)
{
return (x > y)? x: y;
}
int main()
{
cout << myMax<int>(3, 7) << endl; // Call myMax for int
cout << myMax<double>(3.0, 7.0) << endl; // call myMax for double
cout << myMax<char>('g', 'e') << endl; // call myMax for char
return 0;
}
Class templates
We also have the possibility to write class templates, so that a class can have
members that use template parameters as types. For example:
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.
class Box {
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};
#include <iostream> // Note: printWidth() is not a member function of any
class.
using namespace std; void printWidth( Box box ) {
/* Because printWidth() is a friend of Box, it can
class Box { directly access any member of this class */
double width; cout << "Width of box : " << box.width <<endl;
}
public:
friend void printWidth( Box box ); // Main function for the program
void setWidth( double wid ); int main() {
}; Box box;
return 0;
Lecture 14
Vector
(Source:https://www.geeksforgeeks.org/vector-in-cpp-stl/)
Vectors are same as dynamic arrays with the ability to
resize itself automatically when an element is inserted or
deleted, with their storage being handled automatically by
the container. Vector elements are placed in contiguous
storage so that they can be accessed and traversed using
iterators. In vectors, data is inserted at the end. Inserting
at the end takes differential time, as sometimes there may
be a need of extending the array. Removing the last
element takes only constant time because no resizing
happens. Inserting and erasing at the beginning or in the
middle is linear in time.
#include <iostream>
#include <vector>
int main()
{
vector<int> g1;
return 0;
}
Output of begin and end: 1 2 3 4 5
Output of cbegin and cend: 1 2 3 4 5
Output of rbegin and rend: 5 4 3 2 1
Output of crbegin and crend : 5 4 3 2 1
begin() – Returns an iterator pointing to the first element in the vector
end() – Returns an iterator pointing to the theoretical element that follows the last
element in the vector
rbegin() – Returns a reverse iterator pointing to the last element in the vector
(reverse beginning). It moves from last to first element
rend() – Returns a reverse iterator pointing to the theoretical element preceding the
first element in the vector (considered as reverse end)
cbegin() – Returns a constant iterator pointing to the first element in the vector.
cend() – Returns a constant iterator pointing to the theoretical element that follows
the last element in the vector.
crbegin() – Returns a constant reverse iterator pointing to the last element in the
vector (reverse beginning). It moves from last to first element
crend() – Returns a constant reverse iterator pointing to the theoretical element
preceding the first element in the vector (considered as reverse end)
Difference between iterator and constant iterator
A const_iterator is an iterator that points to const content. This iterator can be
increased and decreased (unless it is itself also const), just like theiterator
returned by vector::begin, but it cannot be used to modify the contents it points to,
even if the vector object is not itself const.
for (auto i = g1.begin(); i != g1.end(); ++i)
vector<int> g1; {
*i=10- *i;
for (int i = 1; i <= 5; i++) cout << *i << " "; //Possible
}
g1.push_back(i); for (auto i = g1.cbegin(); i != g1.cend(); ++i)
{
*i=10-*i;
cout << *i << " "; //not possiblle
}
auto in C++ loop
auto a = 2; // a is an interger
auto b = 8.7; // b is a double
auto c = a; // c is an integer
Another loop of auto
#include <iostream> Output of begin and end: 1
#include <vector> 2345
int main()
{
vector<int> g1;
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); // Declare box1
Box Box2(8.5, 6.0, 2.0); // 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;
}
C++ Exception Handling
exception.
blocks.
#include <iostream> try {
using namespace std; z = division(x, y);
cout << z << endl;
double division(int a, int b) { } catch (const char*
if( b == 0 ) { msg) {
throw "Division by zero condition!"; cerr << msg << endl;
} }
return (a/b);
} return 0;
}
int main () {
int x = 50;
int y = 0;
double z = 0;
typedef in C++
(https://codescracker.com/cpp/cpp-user-defined-data-types.htm )
C++ allows you to define explicitly new data type names by using the keyword
typedef. Using typedef doest not actually create a new data class, rather it defines a
new name for an existing type. This can increase the portability of a programas only
the typedef statements would have to be changed.
getch();
}
Lecture 15
C++ Pointers
#include <iostream>
for (int i = 0; i < MAX; i++) {
using namespace std; cout << "Value of var["
const int MAX = 3; << i << "] = ";
cout << *ptr[i] << endl;
int main () { }
int var[MAX] = {10, 100, 200};
int *ptr[MAX]; return 0;
}
for (int i = 0; i < MAX; i++) {
ptr[i] = &var[i]; // assign the
address of integer.
}
C++ Pointer to Pointer (Multiple Indirection)
int main () {
ofstream myfile;
myfile.open ("example.txt");
myfile << "Writing this to a file.\n";
myfile.close();
return 0;
}
Where filename is a string representing the name of the file to be opened, and
mode is an optional parameter with a combination of the following flags:
ll 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:
ofstream myfile;
myfile.open ("example.bin", ios::out | ios::app | ios::binary);
ios::app All output operations are performed at the end of the file,
appending the content to the current content of the file.
ios::tru If the file is opened for output operations and it already
nc existed, its previous content is deleted and replaced by the
new one.
Each of the open member functions of classes ofstream, ifstream and fstream
has a default mode that is used if the file is opened without a second
argument:
ifstream ios::in
int main () {
ofstream myfile ("example.txt");
if (myfile.is_open())
{
myfile << "This is a line.\n";
myfile << "This is another line.\n";
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
//reading a text file else cout << "Unable to
#include <iostream> open file";
#include <fstream>
#include <string> return 0;
using namespace std; }
int main () {
string line; This is a line.
ifstream myfile ("example.txt"); This is another line.
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
}
myfile.close();
}
Checking state flags
The following member functions exist to check for specific states of a stream (all of
them return a bool value):
bad() :Returns true if a reading or writing operation fails. For example, in the case
that we try to write to a file that is not open for writing or if the device where we try
to write has no space left.
fail() :Returns true in the same cases as bad(), but also in the case that a format
error happens, like when an alphabetical character is extracted when we are trying
to read an integer number.
eof() :Returns true if a file open for reading has reached the end.
get and put stream positioning
All i/o streams objects keep internally -at least- one internal position:
ifstream, like istream, keeps an internal get position with the location of the
element to be read in the next input operation.
ofstream, like ostream, keeps an internal put position with the location where
the next element has to be written.
Finally, fstream, keeps both, the get and the put position, like iostream.
These internal stream positions point to the locations within the stream
where the next reading or writing operation is performed. These positions
can be observed and modified using the following member functions:
tellg() and tellp()
These two member functions with no parameters return a value of the
member type streampos, which is a type representing the current get
position (in the case of tellg) or the put position (in the case of tellp).
seekg() and seekp()
These functions allow to change the location of the get and put
positions. Both functions are overloaded with two different prototypes.
The first form is:
seekg ( position );
seekp ( position );
int main () {
streampos begin,end;
ifstream myfile ("example.bin", ios::binary);
begin = myfile.tellg();
myfile.seekg (0, ios::end);
end = myfile.tellg();
myfile.close();
cout << "size is: " << (end-begin) << " bytes.\n";
return 0;
}