01 Intro-Cpp
01 Intro-Cpp
01 Intro-Cpp
1
CENG 213
Instructor: Yusuf Sahillioğlu
Office: B107
Email: ys@ceng.metu.edu.tr
Lecture Hours:
• Tue
Web Page: http://user.ceng.metu.edu.tr/~ys/ceng707-dsa/
Follow odtuclass as well.
Playlist:
https://www.youtube.com/playlist?list=PLamOUbhy_opKnRsYs
OPvkw3lBEiaL0VjY
2
Course Description
Course Objectives: To introduce abstract concepts for data
organization and manipulation, to show how these concepts
are useful in problem solving.
4
Course Outline
• Overview of object-oriented programming with
C++ [chapter 1]
• Algorithm analysis [chapter 2]
• Sorting [chapter 7]
• Lists, stacks, queues [chapter 3]
• Trees [chapter 4]
• Priority queues [chapter 6]
• Hashing [chapter 5]
• Graphs [chapter 9]
5
Motivational Example # 1
• All these structures are there to efficiently store
and process data
• Even a simple data structure you already know
may be very useful if used in the right context
• Store nxn entries of an N-matrix in an array
– Huge profit considering n=1 million, usual case
– Column 1, column n, diagonal (remaining)
– Size of the compact array A?
6
Motivational Example # 1
• All these structures are there to efficiently store
and process data
• Even a simple data structure you already know
may be very useful if used in the right context
• Store nxn entries of an N-matrix in an array
– Huge profit considering n=1 million, usual case
– Column 1, column n, diagonal (remaining)
– 3n-2
– Implement set(i,j,v) to update A[] accordingly
7
Motivational Example # 1
• All these structures are there to efficiently store
and process data
• Even a simple data structure you already know
may be very useful if used in the right context
• Store nxn entries of an N-matrix in an array
– Huge profit considering n=1 million, usual case
– Column 1, column n, diagonal (remaining)
– 3n-2
– if (j==1) A[i] = v;
else if (j==n) A[n+i] = v;
else if (i==j) A[2n+i-1] = v;
8
Motivational Example # 2
• All these structures are there to efficiently store
and process data
• We did 2D array 1D array.
• Now do 1D array auxiliary 1D array.
• Problem: find the sum of a subarray quickly:
sumq(3, 6) = 19
9
Motivational Example # 2
• All these structures are there to efficiently store
and process data
• We did 2D array 1D array.
• Now do 1D array auxiliary 1D array.
• Problem: find the sum of a subarray quickly:
sumq(3, 6) = 19
Slower way
10
Motivational Example # 2
• All these structures are there to efficiently store and
process data
• We did 2D array 1D array.
• Now do 1D array auxiliary 1D array.
• Problem: find the sum of a subarray quickly:
sumq(3, 6) = 19
Auxiliary Prefix Sum Array:
Cooler/faster way
11
Motivational Example # 2
• All these structures are there to efficiently store and
process data
• We did 2D array 1D array.
• Now do 1D array auxiliary 1D array.
• Problem: find the sum of a subarray quickly:
sumq(3, 6) = 19
Auxiliary Prefix Sum Array:
Cooler/faster way
sumq(0,6) - sumq(0,2) = 27 – 8.
12
Motivational Example # 2
• All these structures are there to efficiently store and
process data
• We did 2D array 1D array.
• Now do 1D array auxiliary 1D array.
• Problem: find the sum of a subarray quickly.
• How to compute Prefix Sum Array P?
Array:
P:
13
Motivational Example # 2
• All these structures are there to efficiently store
and process data
• We did 2D array 1D array.
• Now do 1D array auxiliary 1D array.
• Problem: find the sum of a subarray quickly.
• How to compute Prefix Sum Array P?
– Dead simple application of dynamic programming:
• P[0]=A[0]; for(i=1 to n-1) P[i]=P[i-1]+A[i];
14
Motivational Example # 2
• All these structures are there to efficiently store
and process data
• We did 2D array 1D array.
• Now do 2D array auxiliary 1D array.
15
Motivational Example # 2
• All these structures are there to efficiently store and process data
• We did 2D array 1D array.
• Now do 2D array auxiliary 1D array.
• Sum of gray subarray: S(A) - S(B) - S(C) + S(D) where S(X) is the sum of values in a
rectangular subarray from the upperleft corner to the position of X.
16
Programming in C++
• C++
– Improves on many of C's features
– Has object-oriented capabilities
• Increases software quality and reusability
– Developed by Bjarne Stroustrup at Bell Labs
• Called "C with classes"
• C++ (increment operator) - enhanced version of C
– Superset of C
• Can use a C++ compiler to compile C programs
• Gradually evolve the C programs to C++
17
Object Oriented Programming
The emphasis is on creating a set of tools which can be
used cleanly, with a minimum knowledge about
implementation in the user’s driver files. The following
concepts are relevant to accomplishing clean interface:
1. Data Abstraction
– Providing only essential information to the outside world and
hiding their background details, i.e., to represent the needed
information in program without presenting the details
• TV: you can turn on and off, change the channel, adjust the volume, BUT you do not
know its internal details, that is, you do not know how it receives signals over the air
or through a cable, how it translates them, and finally displays them on the screen.
• sort: you can sort an array with this C++ call, BUT you do not know the algorithm.
18
Object Oriented Programming
1. Data Abstraction
– Example: The public members
addNum and getTotal are the
interfaces to the outside
world and a user needs to
know them to use the class.
The private member total is
something that the user
doesn't need to know about,
but is needed for the class to
operate properly.
19
Object Oriented Programming
2. Information hiding
– Example: Restrict access to data so that
it can be manipulated only in
authorized ways. Separate
class declarations from
implementation (e.g. public,
private in C++).
20
Object Oriented Programming
3. Encapsulation
– bundling of data with the methods (or other functions) operating
on that data (implementation of the methods).
21
C++ Techniques
Relevant techniques include:
1. C++ classes, with private and public members
2. Function and operator name overloading to give
"natural" function calls
3. Templates to allow the same code to be used on
a variety of different data types
4. A clean built-in I/O interface, which itself
involves overloading the input and output
operators
Learning these techniques is much of what C++
is all about.
22
A Basic C++ Program
#include <iostream> //input/output
#include <math.h> //usual C lib header file for math
int main()
{
float x;
cout << "The square root of " << x << " is: "
<< sqrt(x) << endl; //see comments part
}
23
A Basic C++ Program
cout << "Enter a real number: " << endl;
Here, you don't need to understand how cout displays the text on the user's
screen. You need to only know the public interface and the underlying
implementation of cout is free to change. //Data Abstraction
In C++, all I/O is done by classes. A class is set up to handle input and output
streams. Output to the screen is handled by the stream with standard name
cout. This is a variable of class ostream. Similarly for cin.
24
A Basic C++ Program
// second C++ program
#include <iostream>
int main(){
int a=23;
int b=34;
25
A Basic C++ Program
// third C++ program
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
double a=15.2;
double b=34.3434343;
return 0;
}
26
A Basic C++ Program
// third C++ program
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
double a=15.2;
double b=34.3434343;
return 0;
}
27
Classes and Objects
• Class: a type definition that includes both
– data properties, and
– operations permitted on that data
• Object: a variable that
– is declared to be of some Class
– therefore includes both data and operations for that
class
• Appropriate usage:
“A variable is an instance of a type.”
“An object is an instance of a class.”
28
Basic Class Syntax
• A class in C++ consists of its members.
– A member can be either data or functions.
• The functions are called member functions
(or methods)
• Each instance of a class is an object.
– Each object contains the data components
specified in class.
– Methods/functions are used to act on an
object.
29
Class syntax - Example
// A class for simulating an integer memory cell
class IntCell
{
public:
IntCell( )
{ storedValue = 0; }
constructors
IntCell(int initialValue )
{ storedValue = initialValue;}
int read( )
{ return storedValue; }
private:
int storedValue;
};
30
Class Members
• Public member is visible to all routines and may
be accessed by any method in any class.
• Private member is not visible to non-class
routines and may be accessed only by methods in its
class.
• Typically,
– Data members are declared private
– Methods are made public
• Restricting access is known as information hiding.
31
Class Members
32
Constructors
• A constructor is a method that executes when an
object of a class is declared and sets the initial state
of the new object.
• A constructor
– has the same name with the class,
– no return type
– has zero or more parameters (the constructor
without an argument is the default constructor)
• There may be more than one constructor defined
for a class.
• If no constructor is explicitly defined, one that
initializes the data members using language defaults
is automatically generated.
33
Extra Constructor Syntax
// A class for simulating an integer memory cell
class IntCell
{
public: Single
IntCell( int initialValue = 0 ) constructor
: storedValue( initialValue) { } (instead of
two)
int read( ) const
{ return storedValue; }
34
Object Declaration
• In C++, an object is declared just like a
primitive type.
#include <iostream>
using namespace std;
#include "IntCell.h"
int main()
{
//correct declarations
IntCell m1;
IntCell m2 ( 12 );
IntCell *m3;
// incorrect declaration
Intcell m4(); // this is a function declaration,
// not an object
35
Object use in driver program
// program continues
m1.write(44);
m2.write(m2.read() +1);
cout << m1.read() << " " << m2.read() << endl;
m3 = new IntCell;
cout << "m3 = " << m3->read() << endl;
return 0;
}
36
Example: Class Time
class Time {
public:
Time( int = 0, int = 0, int = 0 ); //default
//constructor
void setTime( int, int, int ); //set hr, min,sec
void printMilitary(); // print am/pm format
void printStandard(); // print standard format
private:
int hour;
int minute;
int second;
};
37
Declaring Time Objects
// Note that implementation of class Time not given
// here.
int main(){
Time t1, // all arguments defaulted
t2(2), // min. and sec. defaulted
t3(21, 34), // second defaulted
t4(12, 25, 42); // all values specified
. . .
}
38
Class Interface and Implementation
• In C++, separating the class interface from its
implementation is common.
– The interface remains the same for a long time.
– The implementations can be modified independently.
– The writers of other classes and modules have to know
the interfaces of classes only.
• The interface lists the class and its members (data
and function prototypes) and describes what can be
done to an object.
• The implementation is the C++ code for the
member functions.
39
Separation of Interface and Implementation
• It is a good programming practice for large-scale
projects to put the interface and implementation
of classes in different files.
• For small amount of coding it may not matter.
• Header File: contains the interface of a class.
Usually ends with .h (an include file)
• Source-code file: contains the implementation of
a class. Usually ends with .cpp (.cc or .C)
• .cpp file includes the .h file with the preprocessor command
#include.
» Example: #include ”myclass.h”
40
Separation of Interface and Implementation
41
Class Interface
#ifndef _IntCell_H_
#define _IntCell_H_
class IntCell
{
public:
IntCell( int initialValue = 0 );
int read( ) const;
void write( int x );
private:
int storedValue;
};
#endif
IntCell class Interface in the file IntCell.h
42
Class Implementation
#include <iostream>
#include “IntCell.h”
using std::cout;
int main()
{
IntCell m; // or IntCell m(0);
m.write (5);
cout << “Cell content : “ << m.read() << endl;
return 0;
}
44
Destructors
• Member function of class
• Performs termination housekeeping before the
system reclaims the object’s memory
• Complement of the constructor
• Name is tilde (~) followed by the class name
• E.g. ~IntCell( );
~ Time( );
• Receives no parameters, returns no value
• One destructor per class
45
Destructors
• A destructor is a special member function of a
class that is executed whenever an object of it's
class goes out of scope or whenever the delete
expression is applied to a pointer to the object of
that class.
46
Destructor Example
class IntCell{
public:
IntCell(int initialValue=0)
{ storedValue = new int (initialValue);}
~IntCell()
{ delete storedValue; }
47
Destructor Example
48
When are Constructors and Destructors Called
• Global scope objects
• Constructors called before any other function (including main)
• Destructors called when main terminates (or exit function
called)
• Automatic local objects
• Constructors called when objects defined
• Destructors called when objects leave scope (when the block
in which they are defined is exited)
• static local objects
• Constructors called when execution reaches the point where
the objects are defined
• Destructors called when main terminates or the exit function is
called
49
Accessor and Modifier Functions
50
Another Example: Complex Class
#ifndef _Complex_H
#define _Complex_H
#endif
51
Complex class Interface in the file Complex.h
Implementation of Complex Class
#include <iostream>
#include <cmath>
#include "Complex.h"
Complex Complex::operator*(Complex rhs) const
{
Complex prod;
prod.re = (re*rhs.re - im*rhs.im);
prod.im = (re*rhs.im + im*rhs.re);
return prod;
}
float Complex::modulus() const
{
return sqrt(re*re + im*im);
}
void Complex::print() const
{
std::cout << "(" << re <<"," << im << ")" << std::endl;
}
c1.print();
return 0;
}
53
A program that uses Complex in file TestComplex.cpp
Function Overloading
• Function overloading:
– Functions with same name and different parameters
– Overloaded functions performs similar tasks
• Function to square ints and function to square floats
int square( int x) {return x * x;}
float square(float x) { return x * x; }
– Program chooses function by signature
• Signature determined by function name and parameter types
• Type safe linkage - ensures proper overloaded function called
54
Function Overloading
• Function overloading:
– Functions with same name and different parameters
– Overloaded functions performs similar tasks
•
55
// Using overloaded functions
#include <iostream>
using std::cout;
using std::endl;
int square( int x ) { return x * x; }
double square( double y ) { return y * y; }
int main()
{
cout << "The square of integer 7 is " << square( 7 )
<< "\nThe square of double 7.5 is " << square( 7.5 )
<< endl;
return 0;
}
56
Overloaded Operators
• An operator with more than one meaning is said to be
overloaded.
2 + 3 3.1 + 3.2 + is an overloaded operator
57
Operator Overloading
• Format
– Write function definition as normal
– Function name is keyword operator followed by the
symbol for the operator being overloaded.
– operator+ would be used to overload the addition
operator (+)
• No new operators can be created
– Use only existing operators
• Built-in types
– You cannot change how two integers are added
58
Overloaded Operators -- Example
What if we want to multiply a complex number with a scalar? Define
another function with the same name but different parameters.
class Complex
{
...
...
};
59
Implementation of Complex Class
Complex Complex::operator*(Complex rhs) const
{
Complex prod;
prod.re = (re*rhs.re - im*rhs.im);
prod.im = (re*rhs.im + im*rhs.re);
return prod;
}
int main()
{
Complex c1, c2(1), c3(1,2);
c1 = c2 * c3 * c2;
c1.print();
c1 = c1 * 5; // translated to c1.operator*(5)
c1.print();
return 0;
}
61
A program that uses Complex in file TestComplex.cpp
Using the class in a Driver File
#include <iostream>
#include "Complex.h"
int main()
{
Complex c1, c2(1), c3(1,2);
c1 = c2 * c3 * c2;
c1.print();
c1 = c1 * 5; // translated to c1.operator*(5)
c1.print();
return 0;
}
62
A program that uses Complex in file TestComplex.cpp
Putting the Scalar to the Left
To support multiplying with a scalar on the left, we must define a new
function that is outside the class scope.
Complex operator*(float k, Complex c)
{
Complex prod;
prod.re = k * re; // Compile Error: cannot access re
prod.im = k * im; // Compile Error: cannot access im
return prod;
}
Note that this function has access errors: an outside function cannot
access the private members of a class! We can solve this in two ways.
63
Solution 1: Setter/Getter Functions
public:
// add the following functions to the class
void setReal(float x) { re = x; }
void setImag(float x) { im = x; }
float getReal() const { return re; }
float getImag() const { return im; }
...
};
64
Solution 1: Setter/Getter Functions
65
Solution 2: Friend Functions
Declare the outside function as the friend of this class. It can then
access the private members of the class.
class Complex
{
...
...
};
66
Solution 2: Friend Functions
Note that the “friend” keyword is not used here. It is only used inside the class (see the previous slide).
67
Friend Classes
A class may declare another class as a friend as well. In that case all
member functions of the “befriended” class can access the private
members of its friend class
class A
{
...
};
class B
{
...
friend A;
};
“A” can access private members of “B” (but not vice versa!!!)
68
69
Exercise 1
• What is the output from the following loops?
a)
for ( int i=0; i < 5 ; i++) {
cout << i;
}
cout<<endl;
b)
for ( int i = 0; i < 10 ; i += 2) {
cout << i << endl ;
}
70
Exercise 2
• What is the output?
int i = 24 ;
while ( i > 0) {
cout << i << endl ;
i /= 2 ;
}
71
Pointers
• Pointer fun video: https://youtu.be/i49_SNt4yfk
• Normal variables contain a specific value (direct
reference)
int count = 7;
count
72
Pointer Variable Declarations and Initialization
• A pointer declaration takes the following form:
type *identifier;
e.g.
int *myPtr;
– Declares a pointer to an int (pointer of type int *)
y yptr y
5 500000 600000 600000 5
yPtr
Address of y
is value of
yptr
74
Pointer Operators
• * (indirection/dereferencing operator)
– Returns an alias of what its operand points to
– *yptr returns y (because yptr points to y)
– * can be used for assignment
*yptr = 7; // changes y to 7
75
int rate;
int *p_rate;
rate = 500;
p_rate = &rate;
p_rate rate
76
Exercise 3
int a, b, *p;
a = b = 7;
p = &a;
// 1st print statement
cout << "*p = " << *p << endl;
*p = 3;
// 2nd print statement
cout << "a = " << a << endl;
p = &b;
*p = 2 * *p - a;
SetToZero(x);
SetToZero(&x);
79
/* Swapping arguments (incorrect version) */
#include <iostream>
tmp = p;
p = q;
q = tmp;
}
tmp = *p; p q
*p = *q;
*q = tmp;
}
82
Example
int n = 5, m = 6; You cannot declare a
int &rn = n; reference without
giving a value.
n = 6;
rn = 7,
cout << n << rn << m << endl;
rn = m ;
cout << n << rn << m << endl;
83
/* Swapping arguments - with reference variables*/
#include <iostream>
tmp = p; p q
p = q;
q = tmp;
}
int main (void)
{ a b
int a = 3; 3 7
int b = 7;
cout << a << b << endl;
swap(a, b);
cout << a << b << endl;
return 0;
}
84
Exercise 4
• What is the output?
void fun1(int *a, int b){
b = b - 1;
*a = *a + b;
cout << *a << " " << b << endl;
}
int main(){
int a=3, b=3;
fun1(&a,b);
cout << a << " " << b << endl;
}
85
Exercise 5
What is the output?
void fun2(int &a, int b){
a = a * 2;
b = a + b;
cout << a << “ “ << b << endl;
}
int main(){
int x=3, y=5;
fun2(x,y);
cout << x << “ “ << y << endl;
}
86
Classes and Objects
• Class: a type definition that includes both
– data properties, and
– operations permitted on that data
• Object: a variable that
– is declared to be of some Class
– therefore includes both data and operations for that
data
• Appropriate usage:
“A variable is an instance of a type.”
“An object is an instance of a class.”
87
Basic Class Syntax
• A class in C++ consists of its members.
– A member can be either data or functions.
• The functions are called member functions
(or methods)
• Each instance of a class is an object.
– Each object contains the data components
specified in class.
– Methods are used to act on an object.
88
Class syntax - Example
// A class for simulating an integer memory cell
class IntCell
{
public:
IntCell( )
{ storedValue = 0; }
constructors
IntCell(int initialValue )
{ storedValue = initialValue;}
int read( )
{ return storedValue; }
private:
int storedValue;
};
89
Object declaration and use
• In C++, an object is declared just like a primitive type.
#include <iostream>
using namespace std;
#include "IntCell.h"
int main()
{
//correct declarations
IntCell m1;
IntCell m2 (8);
IntCell *m3;
90
Object use in driver program
// program continues
m1.write(44);
m2.write(m2.read() +1);
cout << m1.read() << " " << m2.read() << endl;
m3 = new IntCell;
cout << "m3 = " << m3->read() << endl;
return 0;
}
91
Dynamic Memory Allocation
• new and delete
– new - automatically creates object of proper size, calls
constructor, returns pointer of the correct type
– delete - destroys object and frees space
– You can use them in a similar way to malloc and free in C.
• Syntax:
– TypeName *typeNamePtr;
– typeNamePtr = new TypeName;
– new creates TypeName object, returns pointer (which typeNamePtr
is set equal to)
– delete typeNamePtr;
– Calls destructor for TypeName object and frees memory
92
Examples
// declare a ptr to user-defined data type
IntCell *ptr1;
int *ptr2;
93
// dynamically allocate array of 23
// IntCell slots
// each will be initialized to 0
ptr1 = new IntCell[23];
94
References
• References are a type of C++ variable that act
as an alias to another variable.
• A reference variable acts just like the original
variable it is referencing.
• References are declared by using an
ampersand (&) between the reference type
and the variable name.
95
Example
int n = 5, m = 6; You cannot declare a
int &rn = n; reference without
giving a value.
n = 6;
rn = 7,
cout << n << rn << m << endl; //776
rn = m ; Makes n equal to m (doesn't make rn refer to m)
96
const Reference
• A const reference will not let you change the
value it references:
• Example:
int n = 5;
const int & rn = n;
rn = 6; // error!!
97
References vs Pointers
Everything that is accomplished by references can be
accomplished by pointers but the syntax of references is
simpler:
Example
int n= 5;
int &rn = n;
int *const p = &n;
*p = 6;
rn = 6; Same effect
Pointer fun video: https://youtu.be/i49_SNt4yfk
98
Pointers and const
There are two different ways that pointers and
const can be intermixed:
1. Constant pointer
2. Pointer to a constant variable
99
Constant Pointer
• A const pointer must be initialized to a value
upon declaration, and its value can not be
changed.
• However, because the value being pointed to is
still non-const, it is possible to change the value
being pointed to via dereferencing the pointer:
102
Example
#include <iostream>
using std::cout;
using std::endl;
int main()
{ int x = 2, z = 4, r1, r2;
r1 = squareByValue(x);
squareByReference( z );
r2 = squareByConstReference(x);
cout << "x = " << x << " z = “ << z << endl;
cout << “r1 = " << r1 << " r2 = " << r2 << endl;
return 0;
}
103
Example (cont.)
int squareByValue( int a )
{
return a *= a; // caller's argument not modified
}
void squareByReference( int &cRef )
{
cRef *= cRef; // caller's argument modified
}
int squareByConstReference (const int& a )
{
// a *= a; not allowed (compiler error)
return a * a;
}
104
Improving the Complex Class
#ifndef _Complex_H Old class:
#define _Complex_H
#endif
105
Complex class Interface in the file Complex.h
Improving the Complex Class
#include <iostream>
#include <cmath>
#include "Complex.h"
3. Const object/variable:
const Complex c1(3, 4);
• Example:
int* pi = new int(6);
Complex *pc = new Complex(3, 5);
delete pi;
delete pc;
108
// Allocate an array of complex objects (calls the
default constructor for each object).
Complex *ptr1 = new Complex [10];
109
Default Arguments Revisited
• In C++ functions can have default arguments
• This is specified in the function declaration (not
the definition):
int foo(int x = 1, int y = 2, int z = 3);
110
Default Arguments Revisited
• Note that it is impossible to suppy a user-defined value for z without also
supplying a value for x and y. That is the following does not work:
• For this reason the default parameters must be the rightmost ones:
foo(,,9); // compile error
111
Function Overloading Revisited
• Functions with the same name and different parameters
• Overloaded functions should perform similar tasks
(otherwise it would be confusing):
• Function to square ints and function to square floats
int square( int x) {return x * x;}
float square(float x) { return x * x;}
112
Function Overloading Revisited
• Functions that only differ by return type cannot be
overloaded:
113
Operator Overloading Revisited
• Remember that we overloaded the * operator for the Complex
class.
• Operator overloading allows us to use existing operators for
user-defined classes.
• The following operators can be overloaded:
115
Example
//The following is a copy constructor
//for Complex class. Since it is same
//as the compiler’s default copy
//constructor for this class, it is
//actually redundant.
116
Example
class MyString
{
public:
MyString(const char* s = ””);
MyString(const MyString& s);
...
private:
int length;
char* str;
};
117
Example (cont.)
MyString::MyString(const MyString& s)
{
length = s.length;
str = new char[length + 1];
strcpy(str, s.str);
}
118
Calling the copy constructor
• Examples:
MyObject a; // default constructor call
MyObject b(a); // copy constructor call
MyObject bb = a; // identical to bb(a) : copy
//constructor call
MyObject c; // default constructor call
c = a; // assignment operator call
119
Assignment by Default:
Memberwise Copy
• Assignment operator (=)
– Sets variables equal, i.e., x = y;
– Can be used to assign an object to another
object of the same type
– Memberwise copy — member by member
copy
myObject1 = myObject2;
– This is shallow copy.
120
this Pointer
• Each class object has a pointer which
automatically points to itself. The pointer is
identified by the keyword this.
• Another way to think of this is that each member
function (but not friends) has an implicit first
parameter; that parameter is this, the pointer
to the object calling that function.
121
Example: overloading operator=
// defining an overloaded assignment operator
Complex & Complex :: operator=(const Complex & rhs )
{
// don't assign to yourself!
if ( this != &rhs ) // note the "address of" rhs
// why?
{
this -> Re = rhs.Re; // correct but
//redundant: means Re = rhs.Re
this -> Imag = rhs.Imag;
}
return *this; // return the calling class object
// enables cascading
}
122
Example
MyString& MyString::operator=(const MyString& rhs)
{
if (this != &rhs) {
delete[] this->str; // donate back useless
memory
this->length = rhs.length;
123
Copy constructor and assignment operator
• Note that the copy constructor is called when a new object is being
created
• The assignment operator is called when an existing object is assigned
to a new object
class MyObject {
public:
MyObject(); // Default constructor
MyObject(const MyObject &a); // Copy constructor
MyObject& operator=(const MyObject& a) // Assignment op.
};
MyObject a; // constructor called
MyObject b = a; // copy constructor called
b = a; // assignment operator called
124
Destructor
• For classes with pointers we also need to define a
destructor to avoid memory leaks
class MyString {
public:
MyString(const char* s = ””);
MyString(const MyString& s);
~MyString(); // destructor
MyString& operator=(const MyString& s);
...
private:
int length;
char* str;
};
125
Destructor
• For classes with pointers we also need to define a
destructor to avoid memory leaks
MyString::~MyString()
{
delete[] str;
}
126
Rule of Three
• Whenever you need to define a copy constructor, assignment operator, or the destructor, you
must define all three of them
• This is known as the rule of three
• In general, for every class that contains pointer members you must define all three functions
127
static Class Members
• Shared by all objects of a class
– Normally, each object gets its own copy of each variable
• Efficient when a single copy of data is enough
– Only the static variable has to be updated
• May seem like global variables, but have class scope
– Only accessible to objects of same class
• Exist even if no instances (objects) of the class exist
• Can be variables or functions
• public, private, or protected
128
Example
In the interface file:
private:
static int count;
...
public:
static int getCount();
...
129
Implementation File
int Complex::count = 0;
int Complex::getCount()
{
return count;
}
Complex::Complex()
{
Re = 0;
Imag = 0;
count ++;
}
130
Driver Program
cout << Complex :: getCount() << endl;
Complex c1;
cout << c1.getCount();
131
Templates
• The template allows us to write routines
that work for arbitrary types without
having to know what these types will be.
• Two types:
– Function templates
– Class templates
132
Function Templates
• A function template is not an actual function;
instead it is a design (or pattern) for a function.
• The compiler creates the actual function based on
the actual types used in the program.
// swap function template.
135
Implementation
• Each member function must be declared as a template.
• All member functions must be implemented in the header file
(so that the compiler can find their definition and replace “T”
with the actual parameter type)
136
Object declarations using
template classes
Form:
class-name <type> an-object;
Interpretation:
– Type may be any defined data type. Class-name
is the name of a template class. The object
an-object is created when the arguments
specified between < > replace their
corresponding parameters in the template class.
137
Example
// Memory cell interface (MemoryCell.h)
private:
T storedValue;
};
138
Class template implementation
// Implementation of class members
m.write(5);
m2.write(6);
f.write(3.5);
cout << “Cell content: ” << m.read() << endl;
cout << “Cell content: ” << m2.read() << endl;
cout << “Cell content: ” << f.read() << endl;
return 0;
}
140
Friend functions - revisited
• A friend function of a class is a nonmember
function of the class, but has access to all members of
the class.
141
Example 1: Complex Class
#include <iostream>
#ifndef _Complex_H
#define _Complex_H
using namespace std;
class Complex
{ private: // default
float Re, Imag;
public:
Complex( float x = 0, float y = 0 )
{ Re = x; Imag = y;}
~Complex() { }
float modulus();
void print() const;
friend void dummy(Complex One); //only main’s dummy has
//access
};
#endif Complex class Interface in the file Complex.h 142
Example: Friend functions of a Class (cont’d)
...
int main(){
Complex MyComplexNo(1,1);
dummy(MyComplexNo);
return 0;
}
143
Example 2: Complex Class
#include <iostream>
#ifndef _Complex_H
#define _Complex_H
using namespace std;
class Complex
{ private:
float Re, Imag;
public:
Complex( float x = 0, float y = 0 )
{ Re = x; Imag = y;}
~Complex() { }
Complex operator* ( Complex & rhs ) const;
float getReal() const;
float getImag() const;
float modulus() const;
friend ostream & operator<< (ostream &os, Complex & rhs);
};
#endif
Complex class Interface in the file Complex.h 144
Using the class in a Driver File
#include <iostream>
#include "Complex.h"
using namespace std;
int main()
{
Complex c1, c2(1), c3(1,2);
float x;
c1 = c2 * c3 * c2;
x = c1.modulus();
147
C++ Error Handling
• In C, errors are reported by returning error codes from
functions:
int read(const char* filename, char data[])
{
FILE* fp = fopen(filename, “r”);
if (fp == NULL)
return -1; // indicate error
148
C++ Error Handling
• In C++, we have a more advanced mechanism called
exceptions
• It uses three keywords: throw, catch, try
• The function that encounters an error throws an exception:
149
C++ Error Handling
• This exception must be caught, otherwise the program will
abnormally terminate:
int main()
{
char data[128];
try {
read(“test.txt”, data);
... // some other code
}
catch(const char* error) {
// if read throws an exception,
// program will continue executing from here
cout << “Error message:” << error << endl;
}
}
150
C++ Error Handling
• Note that we throw an object or a variable, and we catch an
object or a variable. These types should match for the
exception to be caught
• In the previous example we threw a const char* and
caught a const char*, so it was correct
151
Another Example
• We can also throw an object of a user defined class:
class FileReadError
{
};
152
C++ Error Handling
• Then we must update the catch code as well:
int main()
{
char data[128];
try {
read(“test.txt”, data);
}
catch(FileReadError error) {
// if read throws an exception,
// we will come here
}
}
153
C++ Error Handling
• There are many details of exception handling
• In this class, you should only know that the destructors of
the local objects will be called when an exception is thrown:
class A {
public:
~A() { cout << “destructor called” << endl; }
};
154
Example of a try-catch Statement
try
{
// Statements that process personnel data and may throw
// exceptions of type int, string, and SalaryError
}
catch ( int )
{
// Statements to handle an int exception
}
catch ( string s )
{
cout << s << endl; // Prints "Invalid customer age"
// More statements to handle an age error
}
catch ( SalaryError )
{
// Statements to handle a salary error
}
Standard Template Library
• I/O Facilities: iostream
• Garbage-collected String class
• Containers
– vector, list, queue, stack, map, set
• Numerical
– complex
• General algorithms
– search, sort
156
Using the vector
• Vector: Dynamically growing, shrinking array of elements
• To use it include library header file:
#include <vector>
• Vectors are declared as
vector<int> a(4); //a vector called a,
//containing four integers
vector<int> b(4, 3); //a vector of four
// elements, each initialized to 3.
vector<int> c; // 0 int objects
• The elements of an integer vector behave just like ordinary
integer variables
a[2] = 45;
157
Manipulating vectors
• The size() member function returns the
number of elements in the vector.
a.size() returns a value of 4.
• The = operator can be used to assign one
vector to another.
• e.g. v1 = v2, so long as they are vectors of
the same type.
• The push_back() member function allows
you to add elements to the end of a vector.
158
push_back() and pop_back()
vector<int> v;
v.push_back(3);
v.push_back(2);
// v[0] is 3, v[1] is 2, v.size() is 2
v.pop_back();
int t = v[v.size()-1]; //t=3
v.pop_back();
159