views:

86

answers:

5

For example, in the OGRE3D engine, I often see things like

class_name class_name :: operator + (class_name & object)

Instead of

class_name class_name :: operator + (class_name object)

Well it's not that I prefer the second form, but is there a particular reason to use a reference in the input ? Does it has special cases where it is necessary to use a reference instead of a copy-by-value ? Or is a performance matter ?

+3  A: 

It's a performance issue. Passing by reference will generally be cheaper than passing by value (it's basically equivalent to passing by pointer).

On an unrelated note, you probably want the argument to operator+ to be const class_name &object.

Oli Charlesworth
+1, the actual signature should be closer to `type type::operator+( type const }` as a free function (first argument by value, second by const reference)
David Rodríguez - dribeas
not ture... see http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
Inverse
@Inverse: Yes, that's why I say "generally".
Oli Charlesworth
A: 

So that object doesn't get copied from the original parameter. In fact, the preferred way is to pass object as const, and to make operator+ as const member operator:

class_name class_name :: operator + (const class_name& object) const;
AraK
A: 

Passing a reference is much faster than copying the whole instance of your class of course. Also, if there is no copy constructor defined for the class, it could be dangerous to copy it (default copy constructor will just copy pointers and the destructor will delete them for example).

When passing classes to a method or operator, the best is to always pass a reference. You can declare it const to be sure it is not modified to avoid side effects.

Benoit Thiery
not true... http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
Inverse
+1  A: 

It is recommended to implement operator+ in terms of operator+=. First make a copy of the left argument, then modify it, and finally return the copy. Since you are going to copy the left argument anyway, you might just as well do it by using call by value for the left argument:

class_name operator+(class_name x, const class_name& y)
{
    return x += y;
}

In C++0x, you should enable move semantics for the result:

#include <utility>

class_name operator+(class_name x, const class_name& y)
{
    return std::move(x += y);
}
FredOverflow
+2  A: 

Besides the "usual" calling conventions for regular methods, I would note that the operators are somewhat peculiar.

The main reason to use const& instead of pass-by-value is correctness (performance comes second, at least in my mind). If your value may be polymorphic, then a copy means object slicing, which is undefined behavior in general.

Therefore, if you use pass-by-value, you clearly state to your caller that the object will be copied and it should not be polymorphic.

Another reason can be performance. If the class is small and its copy-constructor trivial, it might be faster to copy it than to use indirection (think of an int-like class). There are other cases where pass-by-value can be faster, but in non-inline cases they are rarer.

I do think however that none of these is the real reason and the developers just picked this out of the blue...

... because the real WTF (as they say) is that the operator@ should be declared as free functions to allow argument promotion of the left-hand side argument ...

So if they didn't follow this rule, why would they bother with usual argument passing style ?

Matthieu M.
"... because the real WTF (as they say) is that the operator@ should be declared as free functions to allow argument promotion of the left-hand side argument ..." : can you be more specific ? I don't know what you are talking about and I don't find anything about it...
gokoon