views:

102

answers:

4

When overloading assignment operator of a class in C++, must its parameter be reference?

For example,

class MyClass {
public:
...
MyClass & operator=(const MyClass &rhs);
...
}

Can it be

class MyClass {
public:
...
MyClass & operator=(const MyClass rhs);
...
}

?

Thanks!

+5  A: 

The parameter of an overloaded assignment operator can be any type and it can be passed by reference or by value (well, if the type is not copy constructible, then it can't be passed by value, obviously).

So, for example, you could have an assignment operator that takes an int as a parameter:

MyClass& operator=(int);

The copy assignment operator is a special case of an assignment operator. It is any assignment operator that takes the same type as the class, either by value or by reference (the reference may be const- or volatile-qualified).

If you do not explicitly implement some form of the copy assignment operator, then one is implicitly declared and implemented by the compiler.

James McNellis
Thanks, James! For copy assignment operator, is there any class type not copy constructible? I think all class type at least has a default copy constructor?
Tim
@Tim: Sure: if you have a _private_ user-declared copy constructor for a class, then the copy constructor will be inaccessible (unless you are in a member function or friend of that class) and the class will not be copy constructible. If you declare the copy constructor but do not define it, then the class is not copy constructible at all (and trying to copy-construct an instance would cause linker errors). Both of these techniques are used (usually together) to cause a class not to be copy-constructible.
James McNellis
Thanks! I wonder in what cases a class not to be copyable is wanted?
Tim
@Tim: The most trivial example I can think of is the `scoped_ptr`: http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/scoped_ptr.htm
James McNellis
@Tim: I've created objects that wrap a hardware resource. It would get quite awkward if the copy constructor was allowed there.
sharth
+3  A: 

Generally, it's up to you to decide, there is no must. The first variant is common and "canonic" and is ok for any assignment operator implementation.

When the question is speed, I think you should read this article about passing-by-value technique. This means that in some cases passing by value would be more effective than passing by const reference.

Also to mention, your second variant doesn't need const keyword, because passing by value acts as if a copy was created, so the original object definitely won't be changed.

Kotti
Thanks Kotti! Roughly read it, but don't quite understand why passing by reference is slower than passing by value?
Tim
Well, usually it's not, but the point of this article is that if you're doing an object copy right after you pass it by reference, it would be slower than passing by value and assigning that copy, because of compiler optimizations. That's actually tricky, but isn't totally senseless...
Kotti
+3  A: 

C++ Operator Overloading Guidelines suggest, that the assignment operator gets a const reference. According to the site, the reason is that we do not want to change the argument (since const), but just the left hand side of the operator. Thus it saves time to pass it by reference.

It also points to the reason, why also a reference is returned by the assignment operator - operator chaining. In order to get a = (b = 1) working, it's necessary that (b = 1) returns a reference that can be assigned (=) to a.

phimuemue
+1  A: 

Do you know the copy and swap idiom for exception safe assignment?

MyClass& operator=(const MyClass& rhs)
{
    MyClass copy(rhs);
    swap(copy);
    return *this;
}

The implementation can be simplified (and in some cases sped up) via call by value:

MyClass& operator=(MyClass copy)
{
    swap(copy);
    return *this;
}
FredOverflow