- Forward


Operator Overloading in C++
An Introduction


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Motivation
Back SMYC Forward
  • The Situation:
    • You are writing a digital cookbook that uses "English" units
    • You write a Weight class
  • An Inconvenient Syntax:
    • Weight *flourForCookies, *flourForCake, *totalFlour; . . . totalFlour = new Weight(0,0); totalFlour.increase(flourForCake); totalFlour.increase(flourForCookies);
Motivation (cont.)
Back SMYC Forward
  • A Nicer Syntax:
    • Weight *flourForCookies, *flourForCake, *totalFlour; . . . totalFlour = new Weight(0,0); totalFlour = flourForCake + flourForCookies;
  • Can We Do It?
    • Not in Java
    • In C++ we can overload the + and = operators
Ignoring Some Details to Start
Back SMYC Forward
  • What We Will Ignore Initially:
    • The assignment operator (though it is necessary)
    • Return by value/reference
  • What We Will Focus On Initially:
    • Two different ways of implementing the arithmetic operators
Operator "Functions"
Back SMYC Forward
  • Some Details:
    • Declared outside of the class specification because they are not part of the class
    • Identified using the operator keyword
  • An Example:
    • Weight operator +(Weight a, Weight b);
Operator "Functions" (cont.)
Back SMYC Forward
  • Wherever Possible:
    • The operands should be passed by reference
    • The operands should be declared const (the += operator is an exception)
  • An Example Revisited:
    • Weight operator +(const Weight &a, const Weight &b);
Operator "Functions" (cont.)
Back SMYC Forward
An Example - The Specification
cppexamples/operatoroverloading/functions/Weight.h
 
Operator "Functions" (cont.)
Back SMYC Forward
An Example - The Implementation
cppexamples/operatoroverloading/functions/Weight.cpp
 
Operator "Functions" (cont.)
Back SMYC Forward
An Example - Use
cppexamples/operatoroverloading/functions/Driver.cpp
 
Operator "Methods"
Back SMYC Forward
  • Some Details:
    • Declared in the specification of the class that they operate on
    • Identified using the operator keyword
  • An Example:
    • Weight operator +(const Weight &a) const;
  • A Difficulty:
    • While they are more in keeping with the OOP paradigm they can be somewhat confusing because binary operators look like unary operators, etc...
Operator "Methods" (cont.)
Back SMYC Forward
An Example - The Specification
cppexamples/operatoroverloading/methods/Weight.h
 
Operator "Methods" (cont.)
Back SMYC Forward
An Example - The Implementation
cppexamples/operatoroverloading/methods/Weight.cpp
 
Operator "Methods" (cont.)
Back SMYC Forward
An Example - Use
cppexamples/operatoroverloading/methods/Driver.cpp
 
Return by Value/Reference
Back SMYC Forward
  • Two Observations:
    • The arithmetic operators return an object by value
    • The object that is returned is local
  • Consequences:
    • A copy of the local variable is made and returned
    • The local variable goes out of scope after the return
  • Implications:
    • You must write an explicit copy constructor unless the class is very simple (e.g., has only values as attributes)
    • Your destructor must be correct or memory will leak each time a copy is made and deleted
The Assignment Operator
Back SMYC Forward
  • Which Approach to Use:
    • The operator "method" approach (see both examples above)
  • What Needs to be Returned:
    • The obvious answer is that nothing needs to be returned (i.e., it should be void) since it is a "setter"
  • An Interesting Situation:
    • Suppose you want to write w = u = v;?
The Assignment Operator (cont.)
Back SMYC Forward
  • Fixing this Problem:
    • Return the calling object
  • The Specification:
    • Weight operator=(const Weight &rhs);
  • The Implementation:
    • Weight Weight::operator =(const Weight &rhs) { pounds = rhs.pounds; ounces = rhs.ounces; // We must return an object so must dereference this return *this; }
The Assignment Operator (cont.)
Back SMYC Forward
  • An Observation:
    • A copy is being made for every assignment
  • A Fix:
    • Return by reference
  • The Implementation:
    • Weight& Weight::operator =(const Weight &rhs) { pounds = rhs.pounds; ounces = rhs.ounces; return *this; }
  • Convince Yourself:
    • The return by reference will not cause problems in this situation (though it will in many other situations)
There's Always More to Learn
Back -