Function overloading refers to defining two different functions
in the same scope that have the same name.
These functions must different in their parameter lists -
either in the number of parameters or in the parameter types.
class Pair
{
int x, y;
public:
Pair();
Pair(int xval, int yval);
int getX();
int getY();
string toString();
Pair add(const Pair& other);
Pair add(int d);
};
#include "Pair.h"
Pair::Pair() {
x = 0;
y = 0;
}
Pair::Pair(int xval, int yval)
{
x = xval;
y = yval;
}
Pair Pair::add(const Pair& other)
{
int xval = x + other.x;
int yval = y + othery.y;
return Pair(xval, yval);
}
Pair Pair::add(int d)
{
int xval = x + d;
int yval = y + d;
return Pair(xval, yval);
}
...
#include "Pair.h"
int main()
{
Pair p1(2,3);
Pair p2(5,5);
Pair p3, p4;
p3 = p1.add(p2);
p4 = p1.add(1);
cout << "Expecting p3 = (7,8)" << endl;
cout << "p3 = " << p3.toString() << endl;
cout << "Expecting p4 = (3,4)" << endl;
cout << p4.toString() << endl;
return 0;
}
In C++, it is possible to overload operators in addition
to overloading functions.
For example, we can overload the + operator with some
restrictions.
An example restriction is that you can't overload the meaning
of operators for basic types (non-class types) like int, float,
double, char, etc.
So you can't make 4 + 2 be 42 or any other arbitrary value
other than 6.
You can overload operators if one or more of the operands is of
class type.
We would like to write
Pair p1(2,3);
Pair p2(5,5);
Pair p3, p4;
p3 = p1 + p2; // instead of p1.add(p2)
p4 = p1 + 1; // instead of p1.add(1)
Note that the values assigned to p3 and p4 don't change, we are
just able to write the operator + instead of the
member function add. But the implementation will be the same!
How do you declare and implement an new meaning for an
operator. That is, how do you overload an operator?
We already know how to overload a function.
The trick to overloading an operator is that in C++,
each operator has a corresponding function name.
To overload the operator, just overload its function!
But what is the name of the function that corresponds to the
operator +?
Operator |
Operator Function Name |
+ |
operator+ |
- |
operator- |
* |
operator* |
/ |
operator/ |
And so on...
Almost all operators can be overloaded. The member selection
operator "." is one exception.
However, ->, <<, and >> are also operators and
they can be overloaded.
We want to define + to mean the same thing as the
add member function of Pair.
So the new definition of + for Pair is naturally defined
as a member of the Pair class.
Recall we want to use + this way:
Pair p1(2,3);
Pair p2(5,5);
Pair p;
p = p1 + p2;
But to implement this we need to write a member function named
operator+
Here is the revised Pair.h
class Pair
{
int x, y;
public:
Pair();
Pair(int xval, int yval);
int getX();
int getY();
string toString();
Pair add(const Pair& other);
Pair add(int d);
Pair operator+(const Pair& other);
Pair operator+(int d);
};
Note the operator+ functions are declared (and
implemented) with the same parameters as the corresponding
add member functions.
For example, the Pair.cpp file would contain the same member
function implementations, but with 2 more for the
operator+ members:
Pair Pair::add(const Pair& other)
{
int xval = x + other.x;
int yval = y + othery.y;
return Pair(xval, yval);
}
Pair Pair::operator+(const Pair& other)
{
int xval = x + other.x;
int yval = y + othery.y;
return Pair(xval, yval);
}
The compiler (but not programmers) look at
Pair p1(2,3);
Pair p2(5,5);
Pair p3, p4;
p3 = p1.add(p2);
p4 = p1 + p2;
like this
Pair p1(2,3);
Pair p2(5,5);
Pair p3, p4;
p3 = p1.add(p2);
p4 = p1.operator+(p2);
#include "Pair.h"
int main()
{
Pair p1(2,3);
Pair p2(5,5);
Pair p3, p4;
p3 = p1 + p2; // instead of p1.add(p2);
p4 = p1 + 1; // instead of p1.add(1);
cout << "Expecting p3 = (7,8)" << endl;
cout << "p3 = " << p3.toString() << endl;
cout << "Expecting p4 = (3,4)" << endl;
cout << p4.toString() << endl;
return 0;
}
For numbers, of course
a + 1 is the same as 1 + a
So we might want to write
Pair p1(2,3);
Pair p2(5,5);
Pair p;
p = 1 + p1; // PROBLEM
The expression
1 + p1
cannot mean
1.operator+(p1)
since 1 is not a Pair.
We can still make this work by providing one more function to
overload operator+.
But it can't be a member function of the Pair class, since the
left operand is an ordinary integer, not a Pair.
A non-member operator+ function can/must be called without
using the "." member selection.
But this operator will still need 2 operands - the integer and
the Pair.
Here is the member operator+ that works for
For
Pair p1(2,3);
Pair p;
p = p1 + 1;
Here is the member operator+ that works
Pair Pair::operator+(d)
{
int xval = x + d;
int yval = y + d;
return Pair(xval, yval);
}
The non-member operator+ that would work for
Pair p1(2,3);
Pair p;
p = 1 + p;
might be expected to be
Pair operator+(int d, const Pair& other)
{
int xval = d + other.x;
int yval = d + other.y;
return Pair(xval, yval);
}
But other.x is illegal!
Since this operator+ is not a member function it can't access
the private members of Pair!
We can easily fix this by using the public getX and
getY
Pair operator+(int d, const Pair& other)
{
int xval = d + other.getX();
int yval = d + other.getY();
return Pair(xval, yval);
}
This non-member operator+ logically belongs with the
Pair class. A class is a unit that keeps the related member
functions of the class declared in one place (the Pair.h file) and
defined in one place (the Pair.cpp file).
But where can we put the non-member operator+
We could declare it in the Pair.h file, but outside the
class declaration:
class Pair
{
int x, y;
public:
Pair();
Pair(int xval, int yval);
int getX();
int getY();
string toString();
Pair add(const Pair& other);
Pair add(int d);
Pair operator+(const Pair& other);
Pair operator+(int d);
};
Pair operator+(int d, const Pair& p);
and write the implementation in the Pair.cpp file
C++ provides an alternative: friend functions of a
class.
A friend function is a non-member function that is
declared inside a class with the friend qualifier.
The friend qualifier tells the compiler this is
not a member function of Pair, but if one of its parameters
is of type Pair, then the friend function can access the private
members of that Pair.
class Pair
{
int x, y;
public:
Pair();
Pair(int xval, int yval);
int getX();
int getY();
string toString();
Pair add(const Pair& other);
Pair add(int d);
Pair operator+(const Pair& other);
Pair operator+(int d);
friend Pair operator+(int d, const Pair& p);
};
In the Pair.cpp file, the friend qualifier is not
repeated.
Pair Pair::operator+(const Pair& other)
{
int xval = x + other.x;
int yval = y + othery.y;
return Pair(xval, yval);
}
// Don't repeat friend in Pair.cpp
Pair operator+(int d, const Pair& other)
{
int xval = d + other.x;
int yval = d + other.y;
return Pair(xval, yval);
}