In the lesson on overloading the arithmetic operators, you learned that when the operator does not modify it’s operands, it’s best to implement the overloaded operator as a friend function of the class. For operators that do modify their operands, we typically overload the operator using a member function of the class.
Overloading operators using a member function is very similar to overloading operators using a friend function. When overloading an operator using a member function:
- The leftmost operand of the overloaded operator must be an object of the class type.
- The leftmost operand becomes the implicit *this parameter. All other operands become function parameters.
Most operators can actually be overloaded either way, however there are a few exception cases:
- If the leftmost operand is not a member of the class type, such as when overloading operator+(int, YourClass), or operator<<(ostream&, YourClass), the operator must be overloaded as a friend.
- The assignment (=), subscript ([]), call (()), and member selection (->) operators must be overloaded as member functions.
Overloading the unary negative (-) operator
The negative operator is a unary operator that can be implemented using either method. Before we show you how to overload the operator using a member function, here’s a reminder of how we overloaded it using a friend function:
class Cents
{
private:
int m_nCents;
public:
Cents(int nCents) { m_nCents = nCents; }
// Overload -cCents
friend Cents operator-(const Cents &cCents);
};
// note: this function is not a member function!
Cents operator-(const Cents &cCents)
{
return Cents(-cCents.m_nCents);
}
Now let’s overload the same operator using a member function instead:
class Cents
{
private:
int m_nCents;
public:
Cents(int nCents) { m_nCents = nCents; }
// Overload -cCents
Cents operator-();
};
// note: this function is a member function!
Cents Cents::operator-()
{
return Cents(-m_nCents);
}
You’ll note that this method is pretty similar. However, the member function version of operator- doesn’t take any parameters! Where did the parameter go? In the lesson on the hidden this pointer, you learned that a member function has an implicit *this pointer which always points to the class object the member function is working on. The parameter we had to list explicitly in the friend function version (which doesn’t have a *this pointer) becomes the implicit *this parameter in the member function version.
Remember that when C++ sees the function prototype Cents Cents::operator-();, the compiler internally converts this to Cents operator-(const Cents *this), which you will note is almost identical to our friend version Cents operator-(const Cents &cCents)!
Overloading the binary addition (+) operator
Let’s take a look at an example of a binary operator overloaded both ways. First, overloading operator+ using the friend function:
class Cents
{
private:
int m_nCents;
public:
Cents(int nCents) { m_nCents = nCents; }
// Overload cCents + int
friend Cents operator+(Cents &cCents, int nCents);
int GetCents() { return m_nCents; }
};
// note: this function is not a member function!
Cents operator+(Cents &cCents, int nCents)
{
return Cents(cCents.m_nCents + nCents);
}
Now, the same operator overloaded using the member function method:
class Cents
{
private:
int m_nCents;
public:
Cents(int nCents) { m_nCents = nCents; }
// Overload cCents + int
Cents operator+(int nCents);
int GetCents() { return m_nCents; }
};
// note: this function is a member function!
Cents Cents::operator+(int nCents)
{
return Cents(m_nCents + nCents);
}
Our two-parameter friend function becomes a one-parameter member function, because the leftmost parameter (cCents) becomes the implicit *this parameter in the member function version.
Most programmers find the friend function version easier to read than the member function version, because the parameters are listed explicitly. Furthermore, the friend function version can be used to overload some things the member function version can not. For example, friend operator+(int, cCents) can not be converted into a member function because the leftmost parameter is not a class object.
However, when dealing with operands that modify the class itself (eg. operators =, +=, -=, ++, –, etc…) the member function method is typically used because C++ programmers are used to writing member functions (such as access functions) to modify private member variables. Writing friend functions that modify private member variables of a class is generally not considered good coding style, as it violates encapsulation.
Furthermore, as mentioned, some specific operators must be implemented as member functions. We’ll be covering most of these in upcoming lessons.
9.7 — Overloading the increment and decrement operators
|
Index
|
9.5 — Overloading unary operators +, -, and !
|
9.7 — Overloading the increment and decrement operators
Index
9.5 — Overloading unary operators +, -, and !
Thanks Alex, this is starting to make cents. ;)
[...] 2007 Prev/Next Posts « 9.4 — Overloading the comparison operators | Home | 9.6 — Overloading operators using member functions » Monday, October 8th, 2007 at 3:09 [...]
[...] 2007 Prev/Next Posts « 9.6 — Overloading operators using member functions | Home | 9.8 — Overloading the subscript operator » Monday, October 15th, 2007 at [...]
Hi
I wonder which is the right way of expressing in running text,the implicit pointer argument that gets passed to member functions.
*this or this
I prefer the latter.
I don’t understand what you are asking.
In operator overloading,using friend function with unary operator only that members are accessed object referenceor ordinary object with data members.in which one is possible?any possible for accessing members using friend function with unary operator?
should be
right? because u have not defined the member functions to be constants?
br,
a typo notice :
“The negative operator is a unary operator”
should be
“an unary”
Hi Alex,
Can you please give me a main function to check out the operator+(), using member function.
In
it looks as though the last operator is a single minus sign. Shouldn’t that be two? as in –
hmm, looks as though I may have fallen into the same trap. – -