SlideShare une entreprise Scribd logo
1  sur  35
Lecture 5




     Operator Overloading &
      Exception Handling




TCP1201 OOPDS                     1
                              1
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


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


                                                              3
Operator Overloading Advantage
•   It provides a simpler way for doing some operations on
    user-defined classes.
•   Consider the following Rational class which
    represents a rational/fraction number, e.g. 1/2, 2/3:
class Rational {
  int num; // numerator
  int den; // denominator
 public:
  Rational (int num=0, int den=1) : num(num), den(den) {}
  int getNum() const { return num; }
  int getDen() const { return den; }
};
Rational multiply (const Rational& r1, const Rational& r2) {
  int n = r1.getNum() * r2.getNum();
  int d = r1.getDen() * r2.getDen();
  return Rational (n, d);
}



                                                               4
Operator Overloading Advantage
•   To multiply rational numbers e.g. 1/2 * 1/3 * 5/6 =
    5/36, we can use the method multiply(), but it
    looks more complex.
int main() {
  Rational r1(1,2), r2(1,3), r3(5,6), r4;
  r4 = multiply(r1, multiply(r2,r3));                Complex
  ...


•   If we overload multiply operator '*', we can write:
int main() {
  Rational r1(1,2), r2(1,3), r3(5,6), r4;           Simple &
  r4 = r1 * r2 * r3;                                 easy to
  ...                                              understand

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


                 int a = b = 0;
                 ++a;                     //   a   = 1
  prefix         b = ++a;                 //   b   = 2, a = 2
                 cout << "a is:" << a;    //   a   is 2
                 cout << "b is:" << b;    //   b   is 2

  postfix        b = a++;              //      b   = 2
                                       //      a   = 3
                 cout << "a is:" << a; //      a   is 3
                 cout << "b is:" << b; //      b   is 2



                                                           7
How to Overload Operators?
We overload an operator by writing a special function with
the keyword operatorS, where S is an operator symbol (+, -
, *, /, !, ++, etc.).
We should overload an operator in a sensible way and meet
general expectation, e.g. don't overload '*' operator to
perform division.
     returntype operatorS (parameters) {
       ...
       return something;
     }

     // For our Rational number multiplication.
     returntype operator* (parameters) {
       ...
       return something;
                                                        8
     }
How to Overload Operators?
The number of parameters depend whether the overloaded
operator is unary or binary.
• Unary operator has 1 parameter.
• Binary operator has 2 parameters.

Since operator '*' is a binary operator hence the number of
parameter is 2.
We are multiplying 2 Rational objects and expecting the
result is also a Rational object, hence the data type of
both parameter and return type should be Rational.
     // For our Rational number multiplication.
     Rational operator* (Rational, Rational) {
       ...
       return Rational(); // return a new object.
     }                                                    9
Parameters & Return Types
• For parameters, use references whenever possible
  (especially when the parameter is a big object).
• Always use pass-by-const reference when the argument will
  not be modified.
• Always try to follow the spirit of the built-in implementations,
  e.g. comparison operators (==, !=, >, etc) generally return a
  bool, so an overloaded version should do the same.
• Operators that return a reference to the original object
  should return a non-const reference to ensure that the result
  can be modified in a later operation., e.g. <<, >>, =, etc.



                                                             10
Overloading Operator* as Non-Friend Function
class Rational {                               Binary operator has
  int num;                                        2 parameters.
  int den;
 public:
                                               int main() {
  Rational (int num = 0, int den = 1)            Rational r1(1,2),
    : num(num), den(den) {}                               r2(1,3),
  void print() const {                                    r3(5,6),
    cout << num << "/" << den << endl;                    r4;
                                                 r4 = r1 * r2 * r3;
  }
                                                 r1.print();
  int getNum() const { return num; }
                                                 r2.print();
  int getDen() const { return den; }
                                                 r3.print();
};                                               r4.print();
Rational operator* (const Rational& r1,        }
                    const Rational& r2) {
  int n = r1.getNum() * r2.getNum();           Output:
                                               1/2
  int d = r1.getDen() * r2.getDen();
                                               1/3
  return Rational (n, d); // Return a new      5/6
                          // Rational object   5/36
}
                                                              11
Overloading Operator* as Friend Function
class Rational {                                  Binary operator has 2
  friend Rational operator* (const Rational&,        parameters.
                              const Rational&);
  int num;                                        int main() {
  int den;                                          Rational r1(1,2),
 public:                                                     r2(1,3),
  Rational (int num=0, int den=1)                            r3(5,6),
    : num(num), den(den) {}                                  r4;
                                                    r4 = r1 * r2 * r3;
  void print() const {
                                                    r1.print();
    cout << num << "/"                              r2.print();
         << den << endl;                            r3.print();
  }                                                 r4.print();
};                                                }
Rational operator* (const Rational& r1,
                                                  Output:
                    const Rational& r2) {         1/2
  int n = r1.num * r2.num;                        1/3
  int d = r1.den * r2.den;                        5/6
  return Rational (n, d); // Return a new         5/36
                           // Rational object
}                                                                 12
Overloading Operator<< and >>
Binary operator as function has 2 parameters
                                                     int main() {
                                                      Rational r1,
class Rational {                                                r2,
 friend istream& operator>> (istream&, Rational&);              r3;
 ...                                                  cin >> r1
};                                                        >> r2;
istream& operator>> (istream& is, Rational& r) {      r3 = r1 * r2;
  is >> r.num >> r.den;                               cout<< r1<<endl
  // r.getNum() & r.getDen() won't work. Why?             << r2<<endl
 return is;                                               << r3;
}                                                    }
ostream& operator<< (ostream& os,
                     const Rational& r) {            Output:
  os << r.getNum() << "/" << r.getDen();             1 2 3 4
  return os;                                         1/2
}                                                    3/4
                                                     3/8




                                                                13
The Increment Operator (‘++’)
Is a unary operator that can be used as both a prefix ( ++x)
and postfix (x++) operator.

If we have overloaded both prefix and postfix versions of the
increment operator for class Rational:
• A prefix call to operator (++x) will generate a call to:
      Rational::operator++() // prefix

• A postfix call to operator (x++) will generate a call to:
      Rational::operator++(int) // postfix

Postfix requires 1 int parameter to differentiate itself from
prefix.
                                                                14
Overloading Operator<
Binary operator has 2 parameters.
class Rational {
  ...
};

bool operator< (const Rational& r1, const Rational&
r2) {
  return r1.getNum() * r2.getDen() <
         r1.getDen() * r2.getNum();
}

int main() {
 Rational r1(1,2), r2(2,3), r3(1,2);
 if (r1 < r2) cout << "r1 is smaller than r2n";
 else          cout << "r1 is NOT smaller than r2n";
 if (r1 < r3) cout << "r1 is smaller than r3n";
 else          cout << "r1 is NOT smaller than r3n";
}
Output:
r1 is smaller than r2
r1 is NOT smaller than r3                               15
Overloading Operator()
To sort an array or vector of your class by different attribute at
different time.
                                                       int main() {
class Point {
                                                        Point pts[3] =
  int x, y;                                                        {Point(3,6),
 public:                                                            Point(5,4),
  Point (int x = 0, int y = 0) : x(x), y(y) { }                     Point(1,2)};
  int getX() const { return x; }                        for (int i=0; i<3; i++)
                                                          cout << pts[i] << " ";
  int getY() const { return y; }
                                                        cout << endl;
};                                                      sort (pts, pts+3,
ostream& operator<< (ostream& os, const Point& p) {           SortByX());
  os << "(" << p.getX() << ", " << p.getY() << ")";     for (int i=0; i<3; i++)
  return os;                                             cout << pts[i] << " ";
                                                        cout << endl;
}
                                                        sort (pts, pts+3,
struct SortByX {                                              SortByY());
  bool operator() (const Point& p1, const Point& p2)    for (int i=0; i<3; i++)
  { return p1.getX() < p2.getX(); }                      cout << pts[i] << " ";
};                                                     }
struct SortByY {
                                                       Output:
  bool operator() (const Point& p1, const Point& p2)   (3, 6) (5, 4) (1, 2)
  { return p1.getY() < p2.getY(); }                    (1, 2) (3, 6) (5, 4)
};                                                     (1, 2) (5, 4) (3, 6)
                                                                              16
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.


                                                           17
Exception Example: Division By Zero
  How to deal with the error below?

double divide (double x, double y) {
  return x / y;    // divide by 0 if y = 0
}
int main() {
  double x, y;
  cin >> x >> y;
  cout << "Result = " << divide (x, y);
}




                                             18
Exception Example: Division By Zero
A solution is shown below. It works but the codes that
handles the error mixes with the codes for division, making
the codes harder to read (is if for division and else for
error handling, or the other way? No direct indication from
if/else keywords alone.

double divide (double x, double y) {
  return x / y;        // divide by 0 if y = 0
}
int main() {
  double x, y;
  cin >> x >> y;
  if (y == 0) cout << "Cannot divide by zeron";
  else         cout << "Result = " << divide (x, y);
}


                                                         19
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.
     ...
   }                                                    20
try, throw, and catch blocks
throw statement:
• Use keyword throw in try block to signal that
  abnormal condition or error has occurred.
• If the throw statement is executed, the C++ runtime will
  skip the remaining of the try block, and jump to the
  catch block to continue execution.
try {
  // Code that may generate exceptions.
  ...
  if (<error condition is true>)
    throw <Exception object>; // Jump to catch block.
  ... // Will be skipped if throw statement is executed.
}
catch (<Exception type>) {
  // Error handling code.
  ...
}
                                                       21
try, throw, and catch blocks
 catch block:
 • Write the code that catches the thrown exception object
   in catch block. This is the exception handler.
 • Unhandled/Uncaught thrown exception will terminate the
   program.
try {
  // Code that may generate exceptions.
  ...
  if (<error condition is true>)
    throw <Exception object>;
  ...
}
// No code here.
catch (<Exception type>) { // Thrown exception object must
                           // match caught exception type.
  // Error handling code.
  ...
}
                                                         22
Example: try, throw, and catch blocks
double divide (double x, double y) {
  if (y == 0)                            If there is an exception,
    throw y;                             throw it.
  return x / y;
}                                        Put code that may
int main() {                             generate error in
  double x, y;                           try block.
  cin >> x >> y;
  try {
                                         If there is no exception,
    double result = divide (x, y);
    cout << "Result = " << result;       resume execution.
  }
  catch (double a) {                      If there is an exception
    cout << "Cannot divide by zeron";    of type double,
  }                                       catch it.
}




                                                              23
Example: try, throw, and catch blocks
double divide (double x, double y) {     Output1:No exception
  if (y == 0)                            1 2
    throw y;                             Result = 0.5
  return x / y;
}
int main() {                             Output2:With exception
  double x, y;                           1 0
  cin >> x >> y;                         Cannot divide by zero
  try {
    double result = divide (x, y);
    cout << "Result = " << result;
  }
  catch (double a) {                      When an exception is
    cout << "Cannot divide by zeron";    thrown, the codes
  }                                       that appear after the
}                                         throw statement in
                                          the try block is
                                          skipped.

                                                          24
Example: try, throw, and catch blocks
double divide (double x, double y) {     Output1:No exception
  if (y == 0)                            1 2
    throw y;                             Result = 0.5
  return x / y;
}
int main() {                             Output2:With exception
  double x, y;                           1 0
  cin >> x >> y;                         Cannot divide by zero
  try {
    double result = divide (x, y);
    cout << "Result = " << result;
  }
  catch (double a) {                      The type of the object
    cout << "Cannot divide by zeron";    being thrown must
  }                                       match the type of the
}                                         parameter in the
                                          catch block


                                                           25
Example: try, throw, and catch blocks
double divide (double x, double y) {     Output1:No exception
  if (y == 0)                            1 2
    throw y;                             Result = 0.5
  return x / y;
}
int main() {                             Output2:With exception
  double x, y;                           1 0
  cin >> x >> y;                         terminate called after
  try {                                  throwing an instance of
    double result = divide (x, y);       'double'
    cout << "Result = " << result;
  }
  catch (int a) {                         If the type of object
    cout << "Cannot divide by zeron";    being thrown does
  }                                       not match the type of
}                                         the parameter in the
                                          catch block,


                                                           26
Example: try, throw, and catch blocks
Note that exception handling does not require a function to
work.

int main() {
  double x, y;
  cin >> x >> y;
  try {
    if (y == 0)
      throw y;                           Output1:No exception
    double result = x / y;               1 2
    cout << "Result = " << result;
                                         Result = 0.5
  }
  catch (double a) {
    cout << "Cannot divide by zeron";   Output2:With exception
  }                                      1 0
}                                        Cannot divide by zero



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



                                                            28
Example: Exception Propagation
double f2(double x, double y) {        Output:With exception
  if (y == 0) throw y;
  return x / y;                        1 0
}                                      Cannot divide by zero
double f1(double x, double y) {
  return f2(x, y);
}                                       The exception is
double divide (double x, double y) {    propagated in the
  return f1(x, y);                      following order:
}                                       f2(), f1(),
int main() {                            divide(),
  ...                                   main().
  try {
    double result = divide (x, y);      The main() catches
    cout << "Result = " << result;
                                        and handles the
  }
  catch (double a) {                    exception.
  ...


                                                        29
Multiple catch Blocks
Sometimes, we might have many different exceptions
for a small block of code.
try {
  ...
  if (<Error1>) throw <Object of exception type1>;
  if (<Error2>) throw <Object of exception type2>;
  if (<Error3>) throw <Object of exception type3>;
 ...
}
catch (<Exception type1>) {
  // Code that resolves a type1 exception.
}
catch (<Exception type2>) {
  // Code that resolves a type2 exception.
}
catch (<Exception type3>) {
  // Code that resolves a typeN exception.
}
                                                     30
Multiple catch Blocks

But, which catch block will be instigated/invoked?
Depend on the type of exception object.

The type must match exactly, no implicit conversion will
be done by C++. Type double does not match with type
int.

Only one catch block will be executed for an exception.
The catch block that first matches the exception type
would be chosen.




                                                       31
Multiple catch Blocks
void func (int n) {                        int main () {
 try {                                       func (1);
   if (n == 1) throw 11; // int              func (3);
   if (n == 3) throw 3.5; // double          func (4);
   cout << "n is not 1 or 3n";            }
 }
 catch (double a) { // Won't catch int     Output:
   cout << "Catch double " << a << endl;   Catch int 11
 }                                         Catch double 3.5
 catch (int a) { // Match int              n is not 1 or 3
   cout << "Catch int " << a << endl;
 }
}
                                           No implicit
                                           conversion of
                                           exception type in
                                           catch argument


                                                           32
Exception Matching
To catch every possible exception type, use ellipsis "…".

   try {
     ...
   }
   catch (...) { // catches ALL exception types.
     ...
   }


 Limitations of catch (...):
 • You can't tell what type of exception occurred.
 • No argument to reference.
 • Should always be placed as the last catch block.

                                                       33
Exception Matching
void func (int n) {                        int main () {
 try {                                       func (1);
   if (n == 1) throw 11; // int              func (2);
   if (n == 2) throw string("abc");          func (3);
   if (n == 3) throw 3.5; // double          func (4);
   cout << "n is not 1, 2 or 3n";         }
 }
 catch (double a) {
   cout << "Catch double " << a << endl;   Output:
 }                                         Not double nor string
 catch (string a) {                        Catch string abc
   cout << "Catch string " << a << endl;   Catch double 3.5
 }                                         n is not 1, 2 or 3
 catch (...) { // all types
   cout << "Not double nor stringn";
 }
}


                                                                   34
Advantages of Exception Handling

Using try, throw, and catch blocks to handle
exception offer the following advantages:
1. Provide clarify on the section of codes that
   handle the error.
2. You may throw an exception in a
   function/method, and handle it somewhere else.




                                               35

Contenu connexe

Tendances

Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.David Gómez García
 
standard template library(STL) in C++
standard template library(STL) in C++standard template library(STL) in C++
standard template library(STL) in C++•sreejith •sree
 
Scala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsScala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsFrançois Garillot
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingRichardWarburton
 
Dynamic memory allocation in c++
Dynamic memory allocation in c++Dynamic memory allocation in c++
Dynamic memory allocation in c++Tech_MX
 
Collections Framework
Collections FrameworkCollections Framework
Collections FrameworkSunil OS
 
Generics in .NET, C++ and Java
Generics in .NET, C++ and JavaGenerics in .NET, C++ and Java
Generics in .NET, C++ and JavaSasha Goldshtein
 
Stl (standard template library)
Stl (standard template library)Stl (standard template library)
Stl (standard template library)Hemant Jain
 
What's New in C++ 11/14?
What's New in C++ 11/14?What's New in C++ 11/14?
What's New in C++ 11/14?Dina Goldshtein
 
On Parameterised Types and Java Generics
On Parameterised Types and Java GenericsOn Parameterised Types and Java Generics
On Parameterised Types and Java GenericsYann-Gaël Guéhéneuc
 
Stl Containers
Stl ContainersStl Containers
Stl Containersppd1961
 
Memory Management with Java and C++
Memory Management with Java and C++Memory Management with Java and C++
Memory Management with Java and C++Mohammad Shaker
 
Java Generics Introduction - Syntax Advantages and Pitfalls
Java Generics Introduction - Syntax Advantages and PitfallsJava Generics Introduction - Syntax Advantages and Pitfalls
Java Generics Introduction - Syntax Advantages and PitfallsRakesh Waghela
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With ScalaKnoldus Inc.
 
STL ALGORITHMS
STL ALGORITHMSSTL ALGORITHMS
STL ALGORITHMSfawzmasood
 
C++11 smart pointer
C++11 smart pointerC++11 smart pointer
C++11 smart pointerLei Yu
 

Tendances (20)

Memory management in c++
Memory management in c++Memory management in c++
Memory management in c++
 
C++ STL 概觀
C++ STL 概觀C++ STL 概觀
C++ STL 概觀
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
 
standard template library(STL) in C++
standard template library(STL) in C++standard template library(STL) in C++
standard template library(STL) in C++
 
Scala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsScala Collections : Java 8 on Steroids
Scala Collections : Java 8 on Steroids
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional Programming
 
Dynamic memory allocation in c++
Dynamic memory allocation in c++Dynamic memory allocation in c++
Dynamic memory allocation in c++
 
Collections Framework
Collections FrameworkCollections Framework
Collections Framework
 
Generics in .NET, C++ and Java
Generics in .NET, C++ and JavaGenerics in .NET, C++ and Java
Generics in .NET, C++ and Java
 
Stl (standard template library)
Stl (standard template library)Stl (standard template library)
Stl (standard template library)
 
What's New in C++ 11/14?
What's New in C++ 11/14?What's New in C++ 11/14?
What's New in C++ 11/14?
 
On Parameterised Types and Java Generics
On Parameterised Types and Java GenericsOn Parameterised Types and Java Generics
On Parameterised Types and Java Generics
 
Stl Containers
Stl ContainersStl Containers
Stl Containers
 
Memory Management with Java and C++
Memory Management with Java and C++Memory Management with Java and C++
Memory Management with Java and C++
 
Java Generics Introduction - Syntax Advantages and Pitfalls
Java Generics Introduction - Syntax Advantages and PitfallsJava Generics Introduction - Syntax Advantages and Pitfalls
Java Generics Introduction - Syntax Advantages and Pitfalls
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
STL ALGORITHMS
STL ALGORITHMSSTL ALGORITHMS
STL ALGORITHMS
 
The Style of C++ 11
The Style of C++ 11The Style of C++ 11
The Style of C++ 11
 
Advance python
Advance pythonAdvance python
Advance python
 
C++11 smart pointer
C++11 smart pointerC++11 smart pointer
C++11 smart pointer
 

En vedette

Lecture04 polymorphism
Lecture04 polymorphismLecture04 polymorphism
Lecture04 polymorphismHariz Mustafa
 
Lecture03 inheritance
Lecture03 inheritanceLecture03 inheritance
Lecture03 inheritanceHariz Mustafa
 
Lecture01 object oriented-programming
Lecture01 object oriented-programmingLecture01 object oriented-programming
Lecture01 object oriented-programmingHariz Mustafa
 
Fluent interface in c#
Fluent interface in c#Fluent interface in c#
Fluent interface in c#Dror Helper
 
20. Object-Oriented Programming Fundamental Principles
20. Object-Oriented Programming Fundamental Principles20. Object-Oriented Programming Fundamental Principles
20. Object-Oriented Programming Fundamental PrinciplesIntro C# Book
 

En vedette (8)

Lecture04 polymorphism
Lecture04 polymorphismLecture04 polymorphism
Lecture04 polymorphism
 
Lecture03 inheritance
Lecture03 inheritanceLecture03 inheritance
Lecture03 inheritance
 
Lecture01 object oriented-programming
Lecture01 object oriented-programmingLecture01 object oriented-programming
Lecture01 object oriented-programming
 
Basic c#
Basic c#Basic c#
Basic c#
 
Fluent interface in c#
Fluent interface in c#Fluent interface in c#
Fluent interface in c#
 
Lecture09 recursion
Lecture09 recursionLecture09 recursion
Lecture09 recursion
 
Lecture10 trees v3
Lecture10 trees v3Lecture10 trees v3
Lecture10 trees v3
 
20. Object-Oriented Programming Fundamental Principles
20. Object-Oriented Programming Fundamental Principles20. Object-Oriented Programming Fundamental Principles
20. Object-Oriented Programming Fundamental Principles
 

Similaire à Lecture05 operator overloading-and_exception_handling

#ifndef RATIONAL_H   if this compiler macro is not defined #def.pdf
#ifndef RATIONAL_H    if this compiler macro is not defined #def.pdf#ifndef RATIONAL_H    if this compiler macro is not defined #def.pdf
#ifndef RATIONAL_H   if this compiler macro is not defined #def.pdfexxonzone
 
(Rational Class) - use the original files to create the new progra.pdf
(Rational Class) - use the original files to create the new progra.pdf(Rational Class) - use the original files to create the new progra.pdf
(Rational Class) - use the original files to create the new progra.pdfalstradecentreerode
 
C++ Function
C++ FunctionC++ Function
C++ FunctionHajar
 
Ch-4-Operator Overloading.pdf
Ch-4-Operator Overloading.pdfCh-4-Operator Overloading.pdf
Ch-4-Operator Overloading.pdfesuEthopi
 
Reference Parameter, Passing object by reference, constant parameter & Defaul...
Reference Parameter, Passing object by reference, constant parameter & Defaul...Reference Parameter, Passing object by reference, constant parameter & Defaul...
Reference Parameter, Passing object by reference, constant parameter & Defaul...Meghaj Mallick
 
Object Oriented Technologies
Object Oriented TechnologiesObject Oriented Technologies
Object Oriented TechnologiesUmesh Nikam
 
C++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptxC++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptxShashiShash2
 
Assignment 13assg-13.cppAssignment 13assg-13.cpp   @auth.docx
Assignment 13assg-13.cppAssignment 13assg-13.cpp   @auth.docxAssignment 13assg-13.cppAssignment 13assg-13.cpp   @auth.docx
Assignment 13assg-13.cppAssignment 13assg-13.cpp   @auth.docxbraycarissa250
 
Operator overloading2
Operator overloading2Operator overloading2
Operator overloading2zindadili
 

Similaire à Lecture05 operator overloading-and_exception_handling (20)

#ifndef RATIONAL_H   if this compiler macro is not defined #def.pdf
#ifndef RATIONAL_H    if this compiler macro is not defined #def.pdf#ifndef RATIONAL_H    if this compiler macro is not defined #def.pdf
#ifndef RATIONAL_H   if this compiler macro is not defined #def.pdf
 
Lecture17
Lecture17Lecture17
Lecture17
 
Lecture5
Lecture5Lecture5
Lecture5
 
(Rational Class) - use the original files to create the new progra.pdf
(Rational Class) - use the original files to create the new progra.pdf(Rational Class) - use the original files to create the new progra.pdf
(Rational Class) - use the original files to create the new progra.pdf
 
CPP Homework Help
CPP Homework HelpCPP Homework Help
CPP Homework Help
 
Overloading
OverloadingOverloading
Overloading
 
C++ aptitude
C++ aptitudeC++ aptitude
C++ aptitude
 
C++ Function
C++ FunctionC++ Function
C++ Function
 
Ch-4-Operator Overloading.pdf
Ch-4-Operator Overloading.pdfCh-4-Operator Overloading.pdf
Ch-4-Operator Overloading.pdf
 
stack.pptx
stack.pptxstack.pptx
stack.pptx
 
Reference Parameter, Passing object by reference, constant parameter & Defaul...
Reference Parameter, Passing object by reference, constant parameter & Defaul...Reference Parameter, Passing object by reference, constant parameter & Defaul...
Reference Parameter, Passing object by reference, constant parameter & Defaul...
 
Object Oriented Technologies
Object Oriented TechnologiesObject Oriented Technologies
Object Oriented Technologies
 
C++ Functions.ppt
C++ Functions.pptC++ Functions.ppt
C++ Functions.ppt
 
Operators1.pptx
Operators1.pptxOperators1.pptx
Operators1.pptx
 
CP 04.pptx
CP 04.pptxCP 04.pptx
CP 04.pptx
 
C++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptxC++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptx
 
C++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptxC++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptx
 
Assignment 13assg-13.cppAssignment 13assg-13.cpp   @auth.docx
Assignment 13assg-13.cppAssignment 13assg-13.cpp   @auth.docxAssignment 13assg-13.cppAssignment 13assg-13.cpp   @auth.docx
Assignment 13assg-13.cppAssignment 13assg-13.cpp   @auth.docx
 
Operator overloading2
Operator overloading2Operator overloading2
Operator overloading2
 
functions
functionsfunctions
functions
 

Plus de Hariz Mustafa

Topic6decisionmaking
Topic6decisionmakingTopic6decisionmaking
Topic6decisionmakingHariz Mustafa
 
Topic5cognition and problem_solving
Topic5cognition and problem_solvingTopic5cognition and problem_solving
Topic5cognition and problem_solvingHariz Mustafa
 
Problem solving activities
Problem solving activitiesProblem solving activities
Problem solving activitiesHariz Mustafa
 
Exercise answers chapter 1, 2 & 3
Exercise answers chapter 1, 2 & 3Exercise answers chapter 1, 2 & 3
Exercise answers chapter 1, 2 & 3Hariz Mustafa
 
Decision making scenarios
Decision making scenariosDecision making scenarios
Decision making scenariosHariz Mustafa
 
Cognition and problem_solving
Cognition and problem_solvingCognition and problem_solving
Cognition and problem_solvingHariz Mustafa
 
Chapter 6 logical_fallacies_ii
Chapter 6 logical_fallacies_iiChapter 6 logical_fallacies_ii
Chapter 6 logical_fallacies_iiHariz Mustafa
 
Ch08 evaluating arguments
Ch08 evaluating argumentsCh08 evaluating arguments
Ch08 evaluating argumentsHariz Mustafa
 
Chapter 5 logical_fallacies_i
Chapter 5 logical_fallacies_iChapter 5 logical_fallacies_i
Chapter 5 logical_fallacies_iHariz Mustafa
 
Ch03 basic logical_concepts
Ch03 basic logical_conceptsCh03 basic logical_concepts
Ch03 basic logical_conceptsHariz Mustafa
 
Bassham3 powerpoint lecturenotes_ch06
Bassham3 powerpoint lecturenotes_ch06Bassham3 powerpoint lecturenotes_ch06
Bassham3 powerpoint lecturenotes_ch06Hariz Mustafa
 
Bassham3 powerpoint lecturenotes_ch05
Bassham3 powerpoint lecturenotes_ch05Bassham3 powerpoint lecturenotes_ch05
Bassham3 powerpoint lecturenotes_ch05Hariz Mustafa
 
Bassham3 powerpoint lecturenotes_ch04
Bassham3 powerpoint lecturenotes_ch04Bassham3 powerpoint lecturenotes_ch04
Bassham3 powerpoint lecturenotes_ch04Hariz Mustafa
 

Plus de Hariz Mustafa (20)

Topic6decisionmaking
Topic6decisionmakingTopic6decisionmaking
Topic6decisionmaking
 
Topic5cognition and problem_solving
Topic5cognition and problem_solvingTopic5cognition and problem_solving
Topic5cognition and problem_solving
 
Topic2 argument
Topic2 argumentTopic2 argument
Topic2 argument
 
Topic2
Topic2Topic2
Topic2
 
Topic 1
Topic 1Topic 1
Topic 1
 
Problem solving activities
Problem solving activitiesProblem solving activities
Problem solving activities
 
Exercise answers chapter 1, 2 & 3
Exercise answers chapter 1, 2 & 3Exercise answers chapter 1, 2 & 3
Exercise answers chapter 1, 2 & 3
 
Decision making scenarios
Decision making scenariosDecision making scenarios
Decision making scenarios
 
Decision making
Decision makingDecision making
Decision making
 
Cognition and problem_solving
Cognition and problem_solvingCognition and problem_solving
Cognition and problem_solving
 
Chapter 6 logical_fallacies_ii
Chapter 6 logical_fallacies_iiChapter 6 logical_fallacies_ii
Chapter 6 logical_fallacies_ii
 
Chapter 4 language
Chapter 4 languageChapter 4 language
Chapter 4 language
 
Ch08 evaluating arguments
Ch08 evaluating argumentsCh08 evaluating arguments
Ch08 evaluating arguments
 
Chapter 5 logical_fallacies_i
Chapter 5 logical_fallacies_iChapter 5 logical_fallacies_i
Chapter 5 logical_fallacies_i
 
Ch03 basic logical_concepts
Ch03 basic logical_conceptsCh03 basic logical_concepts
Ch03 basic logical_concepts
 
Bassham3 powerpoint lecturenotes_ch06
Bassham3 powerpoint lecturenotes_ch06Bassham3 powerpoint lecturenotes_ch06
Bassham3 powerpoint lecturenotes_ch06
 
Bassham3 powerpoint lecturenotes_ch05
Bassham3 powerpoint lecturenotes_ch05Bassham3 powerpoint lecturenotes_ch05
Bassham3 powerpoint lecturenotes_ch05
 
Bassham3 powerpoint lecturenotes_ch04
Bassham3 powerpoint lecturenotes_ch04Bassham3 powerpoint lecturenotes_ch04
Bassham3 powerpoint lecturenotes_ch04
 
6a
6a6a
6a
 
3a
3a3a
3a
 

Lecture05 operator overloading-and_exception_handling

  • 1. Lecture 5 Operator Overloading & Exception Handling TCP1201 OOPDS 1 1
  • 2. 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 2
  • 3. 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. 3
  • 4. Operator Overloading Advantage • It provides a simpler way for doing some operations on user-defined classes. • Consider the following Rational class which represents a rational/fraction number, e.g. 1/2, 2/3: class Rational { int num; // numerator int den; // denominator public: Rational (int num=0, int den=1) : num(num), den(den) {} int getNum() const { return num; } int getDen() const { return den; } }; Rational multiply (const Rational& r1, const Rational& r2) { int n = r1.getNum() * r2.getNum(); int d = r1.getDen() * r2.getDen(); return Rational (n, d); } 4
  • 5. Operator Overloading Advantage • To multiply rational numbers e.g. 1/2 * 1/3 * 5/6 = 5/36, we can use the method multiply(), but it looks more complex. int main() { Rational r1(1,2), r2(1,3), r3(5,6), r4; r4 = multiply(r1, multiply(r2,r3)); Complex ... • If we overload multiply operator '*', we can write: int main() { Rational r1(1,2), r2(1,3), r3(5,6), r4; Simple & r4 = r1 * r2 * r3; easy to ... understand 5
  • 6. 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.
  • 7. C++ Operators Some unary operators can be used as both prefix and postfix operators, e.g. increment ‘++’ and decrement ‘--’ operators. int a = b = 0; ++a; // a = 1 prefix b = ++a; // b = 2, a = 2 cout << "a is:" << a; // a is 2 cout << "b is:" << b; // b is 2 postfix b = a++; // b = 2 // a = 3 cout << "a is:" << a; // a is 3 cout << "b is:" << b; // b is 2 7
  • 8. How to Overload Operators? We overload an operator by writing a special function with the keyword operatorS, where S is an operator symbol (+, - , *, /, !, ++, etc.). We should overload an operator in a sensible way and meet general expectation, e.g. don't overload '*' operator to perform division. returntype operatorS (parameters) { ... return something; } // For our Rational number multiplication. returntype operator* (parameters) { ... return something; 8 }
  • 9. How to Overload Operators? The number of parameters depend whether the overloaded operator is unary or binary. • Unary operator has 1 parameter. • Binary operator has 2 parameters. Since operator '*' is a binary operator hence the number of parameter is 2. We are multiplying 2 Rational objects and expecting the result is also a Rational object, hence the data type of both parameter and return type should be Rational. // For our Rational number multiplication. Rational operator* (Rational, Rational) { ... return Rational(); // return a new object. } 9
  • 10. Parameters & Return Types • For parameters, use references whenever possible (especially when the parameter is a big object). • Always use pass-by-const reference when the argument will not be modified. • Always try to follow the spirit of the built-in implementations, e.g. comparison operators (==, !=, >, etc) generally return a bool, so an overloaded version should do the same. • Operators that return a reference to the original object should return a non-const reference to ensure that the result can be modified in a later operation., e.g. <<, >>, =, etc. 10
  • 11. Overloading Operator* as Non-Friend Function class Rational { Binary operator has int num; 2 parameters. int den; public: int main() { Rational (int num = 0, int den = 1) Rational r1(1,2), : num(num), den(den) {} r2(1,3), void print() const { r3(5,6), cout << num << "/" << den << endl; r4; r4 = r1 * r2 * r3; } r1.print(); int getNum() const { return num; } r2.print(); int getDen() const { return den; } r3.print(); }; r4.print(); Rational operator* (const Rational& r1, } const Rational& r2) { int n = r1.getNum() * r2.getNum(); Output: 1/2 int d = r1.getDen() * r2.getDen(); 1/3 return Rational (n, d); // Return a new 5/6 // Rational object 5/36 } 11
  • 12. Overloading Operator* as Friend Function class Rational { Binary operator has 2 friend Rational operator* (const Rational&, parameters. const Rational&); int num; int main() { int den; Rational r1(1,2), public: r2(1,3), Rational (int num=0, int den=1) r3(5,6), : num(num), den(den) {} r4; r4 = r1 * r2 * r3; void print() const { r1.print(); cout << num << "/" r2.print(); << den << endl; r3.print(); } r4.print(); }; } Rational operator* (const Rational& r1, Output: const Rational& r2) { 1/2 int n = r1.num * r2.num; 1/3 int d = r1.den * r2.den; 5/6 return Rational (n, d); // Return a new 5/36 // Rational object } 12
  • 13. Overloading Operator<< and >> Binary operator as function has 2 parameters int main() { Rational r1, class Rational { r2, friend istream& operator>> (istream&, Rational&); r3; ... cin >> r1 }; >> r2; istream& operator>> (istream& is, Rational& r) { r3 = r1 * r2; is >> r.num >> r.den; cout<< r1<<endl // r.getNum() & r.getDen() won't work. Why? << r2<<endl return is; << r3; } } ostream& operator<< (ostream& os, const Rational& r) { Output: os << r.getNum() << "/" << r.getDen(); 1 2 3 4 return os; 1/2 } 3/4 3/8 13
  • 14. The Increment Operator (‘++’) Is a unary operator that can be used as both a prefix ( ++x) and postfix (x++) operator. If we have overloaded both prefix and postfix versions of the increment operator for class Rational: • A prefix call to operator (++x) will generate a call to: Rational::operator++() // prefix • A postfix call to operator (x++) will generate a call to: Rational::operator++(int) // postfix Postfix requires 1 int parameter to differentiate itself from prefix. 14
  • 15. Overloading Operator< Binary operator has 2 parameters. class Rational { ... }; bool operator< (const Rational& r1, const Rational& r2) { return r1.getNum() * r2.getDen() < r1.getDen() * r2.getNum(); } int main() { Rational r1(1,2), r2(2,3), r3(1,2); if (r1 < r2) cout << "r1 is smaller than r2n"; else cout << "r1 is NOT smaller than r2n"; if (r1 < r3) cout << "r1 is smaller than r3n"; else cout << "r1 is NOT smaller than r3n"; } Output: r1 is smaller than r2 r1 is NOT smaller than r3 15
  • 16. Overloading Operator() To sort an array or vector of your class by different attribute at different time. int main() { class Point { Point pts[3] = int x, y; {Point(3,6), public: Point(5,4), Point (int x = 0, int y = 0) : x(x), y(y) { } Point(1,2)}; int getX() const { return x; } for (int i=0; i<3; i++) cout << pts[i] << " "; int getY() const { return y; } cout << endl; }; sort (pts, pts+3, ostream& operator<< (ostream& os, const Point& p) { SortByX()); os << "(" << p.getX() << ", " << p.getY() << ")"; for (int i=0; i<3; i++) return os; cout << pts[i] << " "; cout << endl; } sort (pts, pts+3, struct SortByX { SortByY()); bool operator() (const Point& p1, const Point& p2) for (int i=0; i<3; i++) { return p1.getX() < p2.getX(); } cout << pts[i] << " "; }; } struct SortByY { Output: bool operator() (const Point& p1, const Point& p2) (3, 6) (5, 4) (1, 2) { return p1.getY() < p2.getY(); } (1, 2) (3, 6) (5, 4) }; (1, 2) (5, 4) (3, 6) 16
  • 17. 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. 17
  • 18. Exception Example: Division By Zero How to deal with the error below? double divide (double x, double y) { return x / y; // divide by 0 if y = 0 } int main() { double x, y; cin >> x >> y; cout << "Result = " << divide (x, y); } 18
  • 19. Exception Example: Division By Zero A solution is shown below. It works but the codes that handles the error mixes with the codes for division, making the codes harder to read (is if for division and else for error handling, or the other way? No direct indication from if/else keywords alone. double divide (double x, double y) { return x / y; // divide by 0 if y = 0 } int main() { double x, y; cin >> x >> y; if (y == 0) cout << "Cannot divide by zeron"; else cout << "Result = " << divide (x, y); } 19
  • 20. 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. ... } 20
  • 21. try, throw, and catch blocks throw statement: • Use keyword throw in try block to signal that abnormal condition or error has occurred. • If the throw statement is executed, the C++ runtime will skip the remaining of the try block, and jump to the catch block to continue execution. try { // Code that may generate exceptions. ... if (<error condition is true>) throw <Exception object>; // Jump to catch block. ... // Will be skipped if throw statement is executed. } catch (<Exception type>) { // Error handling code. ... } 21
  • 22. try, throw, and catch blocks catch block: • Write the code that catches the thrown exception object in catch block. This is the exception handler. • Unhandled/Uncaught thrown exception will terminate the program. try { // Code that may generate exceptions. ... if (<error condition is true>) throw <Exception object>; ... } // No code here. catch (<Exception type>) { // Thrown exception object must // match caught exception type. // Error handling code. ... } 22
  • 23. Example: try, throw, and catch blocks double divide (double x, double y) { if (y == 0) If there is an exception, throw y; throw it. return x / y; } Put code that may int main() { generate error in double x, y; try block. cin >> x >> y; try { If there is no exception, double result = divide (x, y); cout << "Result = " << result; resume execution. } catch (double a) { If there is an exception cout << "Cannot divide by zeron"; of type double, } catch it. } 23
  • 24. Example: try, throw, and catch blocks double divide (double x, double y) { Output1:No exception if (y == 0) 1 2 throw y; Result = 0.5 return x / y; } int main() { Output2:With exception double x, y; 1 0 cin >> x >> y; Cannot divide by zero try { double result = divide (x, y); cout << "Result = " << result; } catch (double a) { When an exception is cout << "Cannot divide by zeron"; thrown, the codes } that appear after the } throw statement in the try block is skipped. 24
  • 25. Example: try, throw, and catch blocks double divide (double x, double y) { Output1:No exception if (y == 0) 1 2 throw y; Result = 0.5 return x / y; } int main() { Output2:With exception double x, y; 1 0 cin >> x >> y; Cannot divide by zero try { double result = divide (x, y); cout << "Result = " << result; } catch (double a) { The type of the object cout << "Cannot divide by zeron"; being thrown must } match the type of the } parameter in the catch block 25
  • 26. Example: try, throw, and catch blocks double divide (double x, double y) { Output1:No exception if (y == 0) 1 2 throw y; Result = 0.5 return x / y; } int main() { Output2:With exception double x, y; 1 0 cin >> x >> y; terminate called after try { throwing an instance of double result = divide (x, y); 'double' cout << "Result = " << result; } catch (int a) { If the type of object cout << "Cannot divide by zeron"; being thrown does } not match the type of } the parameter in the catch block, 26
  • 27. Example: try, throw, and catch blocks Note that exception handling does not require a function to work. int main() { double x, y; cin >> x >> y; try { if (y == 0) throw y; Output1:No exception double result = x / y; 1 2 cout << "Result = " << result; Result = 0.5 } catch (double a) { cout << "Cannot divide by zeron"; Output2:With exception } 1 0 } Cannot divide by zero 27
  • 28. 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. 28
  • 29. Example: Exception Propagation double f2(double x, double y) { Output:With exception if (y == 0) throw y; return x / y; 1 0 } Cannot divide by zero double f1(double x, double y) { return f2(x, y); } The exception is double divide (double x, double y) { propagated in the return f1(x, y); following order: } f2(), f1(), int main() { divide(), ... main(). try { double result = divide (x, y); The main() catches cout << "Result = " << result; and handles the } catch (double a) { exception. ... 29
  • 30. Multiple catch Blocks Sometimes, we might have many different exceptions for a small block of code. try { ... if (<Error1>) throw <Object of exception type1>; if (<Error2>) throw <Object of exception type2>; if (<Error3>) throw <Object of exception type3>; ... } catch (<Exception type1>) { // Code that resolves a type1 exception. } catch (<Exception type2>) { // Code that resolves a type2 exception. } catch (<Exception type3>) { // Code that resolves a typeN exception. } 30
  • 31. Multiple catch Blocks But, which catch block will be instigated/invoked? Depend on the type of exception object. The type must match exactly, no implicit conversion will be done by C++. Type double does not match with type int. Only one catch block will be executed for an exception. The catch block that first matches the exception type would be chosen. 31
  • 32. Multiple catch Blocks void func (int n) { int main () { try { func (1); if (n == 1) throw 11; // int func (3); if (n == 3) throw 3.5; // double func (4); cout << "n is not 1 or 3n"; } } catch (double a) { // Won't catch int Output: cout << "Catch double " << a << endl; Catch int 11 } Catch double 3.5 catch (int a) { // Match int n is not 1 or 3 cout << "Catch int " << a << endl; } } No implicit conversion of exception type in catch argument 32
  • 33. Exception Matching To catch every possible exception type, use ellipsis "…". try { ... } catch (...) { // catches ALL exception types. ... } Limitations of catch (...): • You can't tell what type of exception occurred. • No argument to reference. • Should always be placed as the last catch block. 33
  • 34. Exception Matching void func (int n) { int main () { try { func (1); if (n == 1) throw 11; // int func (2); if (n == 2) throw string("abc"); func (3); if (n == 3) throw 3.5; // double func (4); cout << "n is not 1, 2 or 3n"; } } catch (double a) { cout << "Catch double " << a << endl; Output: } Not double nor string catch (string a) { Catch string abc cout << "Catch string " << a << endl; Catch double 3.5 } n is not 1, 2 or 3 catch (...) { // all types cout << "Not double nor stringn"; } } 34
  • 35. Advantages of Exception Handling Using try, throw, and catch blocks to handle exception offer the following advantages: 1. Provide clarify on the section of codes that handle the error. 2. You may throw an exception in a function/method, and handle it somewhere else. 35