Académique Documents
Professionnel Documents
Culture Documents
TCP1201 OOPDS
Learning Objectives
Operator Overloading
To understand what is operator overloading
To understand the advantage of operator overloading
To understand how to overload operators as functions
Exception handling
To understand what is exception
To realize the advantages of exception handling
To understand the use of try, throw and catch block
To understand how exception propagation works
To understand how to wrote multiple catch blocks and
exception matching
Operator Overloading
Add capability to an operator via writing a new "special
function" for the same operator but with different data
types and combinations of parameters.
For example, C++'s operator '+':
C++ has built-in support for using operator '+' to add
int or double, and also for concatenating string.
However using operator '+' to add 2 objects of your
(user-defined) class is not automatically supported.
We can write a "function" to make C++ support
adding 2 objects of user-defined class. This process
is called operator overloading.
class Rational {
int num; // numerator
int den; // denominator
public:
Rational (int num=0, int den=1) : num(num), den(den) {}
int getNum() { return num; }
int getDen() { return den; }
};
Rational multiply (Rational& r1, Rational& r2) {
int n = r1.getNum() * r2.getNum();
int d = r1.getDen() * r2.getDen();
return Rational (n, d);
}
int main() {
Rational r1(1,2), r2(1,3), r3(5,6), r4;
r4 = multiply(r1, multiply(r2,r3));
...
Complex
int main() {
Rational r1(1,2), r2(1,3), r3(5,6), r4;
r4 = r1 * r2 * r3;
...
Simple &
easy to
understand
C++ Operators
Operators in C++ are divided into 2 categories based
on the number of arguments they accept:
Unary operators accept one argument
x++, --x, !x, etc.
Binary operators accept two arguments
x+y, x-y, x*y, x<y, x=y, etc.
C++ Operators
Some unary operators can be used as both prefix and postfix
operators, e.g. increment ++ and decrement -- operators.
prefix
int a = b = 0;
++a;
b = ++a;
cout << "a is:" << a;
cout << "b is:" << b;
postfix
b = a++;
//
//
//
//
a
b
a
b
= 1
= 2, a = 2
is 2
is 2
//
//
cout << "a is:" << a; //
cout << "b is:" << b; //
b
a
a
b
= 2
= 3
is 3
is 2
Non-friend
function call
methods.
int main() {
Rational r1(1,2),
r2(1,3),
r3(5,6),
r4;
r4 = r1 * r2 * r3;
r1.print();
r2.print();
r3.print();
r4.print();
}
Output:
1/2
1/3
5/6
5/36
10
Friend function
can access private
member directly.
int main() {
Rational r1(1,2),
r2(1,3),
r3(5,6),
r4;
r4 = r1 * r2 * r3;
r1.print();
r2.print();
r3.print();
r4.print();
}
Output:
1/2
1/3
5/6
5/36
12
int main() {
Rational r1,
r2,
r3;
cin >> r1
>> r2;
r3 = r1 * r2;
cout<< r1<<endl
<< r2<<endl
<< r3;
}
Output:
1 2 3 4
1/2
3/4
3/8
14
15
class SortByX {
public:
bool operator()(Point p1, Point p2)
{ return p1.getX() < p2.getX(); }
};
class SortByY {
public:
bool operator() (Point p1, Point p2)
{ return p1.getY() < p2.getY(); }
};
int main() {
Point pts[3] =
{Point(3,6),
Point(5,4),
Point(1,2)};
for (int i=0; i<3; i++)
cout << pts[i] << " ";
cout << endl;
sort (pts, pts+3,
SortByX());
for (int i=0; i<3; i++)
cout << pts[i] << " ";
cout << endl;
sort (pts, pts+3,
SortByY());
for (int i=0; i<3; i++)
cout << pts[i] << " ";
}
Output:
(3, 6) (5, 4) (1, 2)
(1, 2) (3, 6) (5, 4)
(1, 2) (5, 4) (3, 6)
18
Exception Handling
When a program is executed, unexpected situations may
occur. Such situations are called exceptions.
In other word: An exception is a runtime error caused by
some abnormal conditions.
Example:
Division by zero
Failure of new operator to obtain a requested amount of
memory
Exception handler is code that handles the exception
(runtime error) when it occurs.
19
20
21
Exception Handling
C++ implements exception handling using try, throw
and catch block.
try block:
Write the code that might generate runtime error within
the try block.
try {
// Code that may generate exceptions.
...
if (<error condition is true>)
throw <Exception object>;
...
}
catch (<Exception type>) {
// Error handling code.
...
22
}
25
Output1:No exception
1 2
Result = 0.5
Output2:With exception
1 0
Cannot divide by zero
When an exception is
thrown, the codes
that appear after the
throw statement in
the try block is
skipped.
26
Output1:No exception
1 2
Result = 0.5
Output2:With exception
1 0
Cannot divide by zero
27
Output1:No exception
1 2
Result = 0.5
Output2:With exception
1 0
terminate called after
throwing an instance
of 'double'
28
Output1:No exception
1 2
Result = 0.5
Output2:With exception
1 0
Cannot divide by zero
29
Exception Propagation
If the function containing the throw statement does not
catch the exception, the exception will be propagated up to
the caller of the function until it reaches a try block or the
main function.
In the former case, the try/catch block of the caller
handles the exception if the exception type matches one of
the catch block. Otherwise the exception will be
propagated up again.
If the exception reaches the main function and is not
handled, the program will be terminated.
30
Output:With exception
1 0
Cannot divide by zero
The exception is
propagated in the
following order:
f2(), f1(),
divide(),
main().
The main() catches
and handles the
exception.
31
33
int main () {
func (1);
func (3);
func (4);
}
Output:
Catch int 11
Catch double 3.5
n is not 1 or 3
No implicit
conversion of
exception type in
catch argument
34
Exception Matching
To catch every possible exception type, use ellipsis "".
try {
...
}
catch (...) { // catches ALL exception types.
...
}
Exception Matching
void func (int n) {
try {
if (n == 1) throw 11; // int
if (n == 2) throw string("abc");
if (n == 3) throw 3.5; // double
cout << "n is not 1, 2 or 3\n";
}
catch (double a) {
cout << "Catch double " << a << endl;
}
catch (string a) {
cout << "Catch string " << a << endl;
}
catch (...) { // all types
cout << "Not double nor string\n";
}
}
int main () {
func (1);
func (2);
func (3);
func (4);
}
Output:
Not double nor string
Catch string abc
Catch double 3.5
n is not 1, 2 or 3
36
37