operator overloading: sources disagree

Pages: 12
I've been trying to get smart on operator overloading, but it seems that various sources disagree on how some operators should be overloaded.

A book I'm using, for example, says to overload the addition operator with a function that uses only one parameter, while an online resource says to create one with two.

Before I get into any specific questions, does someone here have a reference source for this information? I'd like it to be simple and clear, not so much like the stuff that the committees put out.

Thanks for any suggestions.
If a binary operator is written as class member, one argument is implicit ( this, pointing to the object itself ). The other argument must be provided explicitly.
If the operator is defined as external function, you have to provide both arguments.

eg:
1
2
3
4
5
6
class C
{
    C operator+ ( const C& other ) const; // member operator +
};

C operator+ ( const C& a, const C& b ); // external operator+ 
Thanks, Bazzy. So...is one method generally preferred over the other?

I just realized that the book I'm using was printed in 1994. My guess is that a few things have changed in C++ since then.
In general, I would say use the class method option if possible. But there are some cases where you would need to (say, you want to overload operator+() for when your class is the second parameter of the operator.
Also, there is a difference between the order of arguments. You must usually provide both a member (or non-member, at your option) version and also a non-member friend.

http://www.cplusplus.com/forum/beginner/26212/#msg139821

Hope this helps.
OK, well, here's what I'm trying to do (unnecessary stuff deleted):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SocReg
{
public:
	SocReg&	operator= (const SocReg &r);
	SocReg	operator+ (const SocReg &r);
	SocReg	operator* (const SocReg &r);
};

SocReg	SocReg::operator+ (const SocReg &r)	// addition operator
{
	SocReg	temp;

	temp.a = a + r.a;

	return temp;
}


So...how many mistakes have I made in this?

Thanks.
Looks fine, though your operator+() and operator*() should be const.
Looks fine, though your operator+() and operator*() should be const.

Well, something's not working. I'll take a closer look. Of course, it's not helping that the Eclipse debugger is giving me odd results, too. (I love learning multiple things at once.)

I always screw up the positioning of the const tag; should it go at the start of the line?
SocReg operator+ const (const SocReg &r);
Should be correct.
Thanks, JoR. And...why exactly is this needed? It's not enough to say const in the argument list?

Edit: I just tried it, and the compiler (actually the editor) flags it as a syntax error.
Last edited on
const on the function indicates it will not modify the this pointer, in essence, making you unable to modify your class variables inside the function.
Thanks, firedraco. So...I assume this is a good thing for a constructor.

Any idea why my compier doesn't like it? I get this message:

/Users/mzimmers/wideband/SoC simulator/modem_simulator/headers/SocReg.h:25: error: declaration of 'operator+' as non-function
/Users/mzimmers/wideband/SoC simulator/modem_simulator/headers/SocReg.h:25: error: expected ';' before 'const'
I think you have to put the const after the function:

SocReg operator+ (const SocReg& r) const;
That's right.
Don't make binary arithmetic operators members, because then the first argument will not participate in "standard conversions". In other words, if you have conversion from int to your user type, and someone does <some int> + <some user type object>, the first argument wont get converted. This is the way the cookie crumbles for member functions in general. The object for the call is of the exact type, it is never converted. If you use friend functions, then the first operand will be converted as would be probably expected. Notice that the second operand will be converted in both cases.

For unary operators you may opt to use member functions, firs because the conversions are not usually desirable then, and second because you may decide to use polymorphism for some reason.

Regards
firedraco and Zhuge: thanks. It works. I don't know that I fully understand it, but...I'll run with it.

simeonz: I'll look at your post more closely in the AM; too tired to process now.

Perhaps someone can tell me why this is failing at link time -- I created a little telltale routine within SocReg:

void display (SocReg r) const;

It works right when called by other member functions, but not from main. The call in main looks like this:

1
2
3
4
	SocReg	d;

	d = a + b + c;     // a, b and c are also members of class SocReg.
	SocReg::display (d);


I get an error message:

../src/main.cpp:20: error: cannot call member function 'void SocReg::display(SocReg) const' without object
Hi ,
I have question here to ask .
can we do as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SocReg
{
public:

	SocReg& operator+ (const SocReg &r);

};

SocReg& SocReg::operator+ (const SocReg &r)	// addition operator
{
	

	this->a +=  r.a;

	return this ;
}
Last edited on
Actually I misquoted. User type conversions are not standard conversions, but what I meant is implicit conversions. Still, here is the practical effect:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct S
{
  S(int value = 0) : value_(value) {}

  S operator + (const S& other) const
  {
    return S(value_ + other.value_);
  }

  int value_;
};

int main()
{
  S a(1);
  S b = a + 2; //This will work, because 2 will be converted to S(2)
  S c = 2 + a; //This will not work, because operator + is member and 2 is not converted
}

Everything will work fine if you define the operator like this:
1
2
3
4
S operator + (const S& left, const S& right)
{
  return S(left.value_ + right.value_);
}

Regards
Anyone have an idea on the problem I mentioned a few posts up? Thanks.
You can either make the display function static
static void display (SocReg r);

or you can make it member function with no argument
void display () const;

and then call it like this:
d.display();

Regards
Pages: 12