Question

C++ Overload Operator as Member and Function at the same time? I am trying to set up operator overloading here.

I have no problem with operator+ overloading as friend and member each case. But when I try to overload + operator as friend ans the friend as member at the same time I get the error.

Kind of confused here. I might try to do something that does not even make sense? Please check my code and see if I can work it out. Case 3 is the ERROR generating case. Thanks!

CASE1 Overload as Friend: Source.cpp

#include <iostream>
using namespace std;
#include "Time.h"
int main () {
Time planning;       Time coding(2, 40);
Time fixing(5, 55);  Time total;
total = coding + fixing;
cout << "coding + fixing = ";
total.Show();
cout << endl;
cin.get();  return 0; }

CASE1 Overload as Friend: Time.h

#pragma once
class Time
{ int hours; int minutes;
public:
Time(void);
~Time(void);
Time(int, int m = 0);
void AddMin(int);
void AddHr(int);
void Reset(int h=0, int m=0);
friend const Time operator+(const Time&amp;, const Time&amp;);
void Show() const; };

CASE1 Overload as Friend: Time.cpp

#include "Time.h"
#include <iostream>
using namespace std;
Time::Time(void) { hours = minutes = 0;}
Time::~Time(void) {}
Time::Time (int h, int m) { hours =h; minutes = m; }
void Time::AddMin(int m) {minutes+=m; hours+=minutes/60; minutes%= 60; }
void Time::Reset(int h, int m) {hours = h; minutes = m;}

const Time operator+(const Time &amp; t1, const Time&amp; t2) {
Time sum;
sum.minutes = t1.minutes + t2.minutes;
sum.hours = t1.hours + t2.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum; }
void Time::Show() const
{ cout << hours << " hours, " << minutes << " minutes"; }

CASE2 Overload as Member: Source.cpp / Time.h / Time.cpp Source.cpp // same

Time.h

const Time operator+(const Time&amp;) const;  // declaration

Time.cpp

const Time Time::operator+(const Time&amp; t) const {
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum; }  // function definition

CASE 3: ERROR; trying to overload operator + as friend and member at the same time Source.cpp // same

Time.h

friend const Time operator+(const Time&amp;) ;  // declaration

Time.cpp

friend const Time operator+(const Time&amp; t) {
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum; }  // function definition
Was it helpful?

Solution

When you provide an operator overload for your type, what you are doing is providing a function to call when the operator appears in code. It does not make sense to provide two definitions when only one can be called and there is no way of selecting it.

That is, you should not have both a member function and a free function overload.

The next thing, which might actually be your confusion is what the meaning of friend is. When you provide a friend declaration, you are declaring a free function and granting that function access to your private members. It is a free function, and as such there is no implicit this argument, thus:

class X {
   friend X operator+(X const &);
};

would declare an overload for operator+ that takes a single argument of type X const& and returns an object of type X. Incidentally, that is a valid operator, just not the one that you mean to overload (it is the unary operator+, as in X x; +x;). Going back to the previous paragraph, it declares a free function, not a member function, there is no implicit this, just like if you had declared:

class X {};
X operator+(X const &);

And because there is no implicit this, minutes and hours by themselves don't make sense inside that function and will fail to compile. (The friend keyword in the definition is also wrong, friend can never appear outside of a class definition).

There is some confusion as of whether friend has any special meaning with respect to operators, it doesn't. It is just a keyword that affects access specifiers. If you can implement the operator in terms of the public interface of your type, it should not be friend in the first place. So if for example you had accessors in Time to obtain the hours and minutes, you could implement the operator as:

class Time { // ...
public:
   Time(int hours, int minutes);
   int hours() const;
   int minutes() const;
};
Time operator+(Time const & lhs, Time const & rhs) {
   return Time(lhs.hours()+rhs.hours(), lhs.minutes()+rhs.minutes());
}

With no friendship involved.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top