7

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!

Tim
  • 1
  • 141
  • 372
  • 590

5 Answers5

9

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
  • 348,265
  • 75
  • 913
  • 977
  • 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 May 30 '10 at 22:52
  • @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 May 30 '10 at 23:27
  • Thanks! I wonder in what cases a class not to be copyable is wanted? – Tim May 31 '10 at 03:46
  • @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 May 31 '10 at 03:51
  • @Tim: I've created objects that wrap a hardware resource. It would get quite awkward if the copy constructor was allowed there. – Bill Lynch May 31 '10 at 06:45
5

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.

Philipp Claßen
  • 41,306
  • 31
  • 146
  • 239
M. Williams
  • 4,945
  • 2
  • 26
  • 27
  • Thanks Kotti! Roughly read it, but don't quite understand why passing by reference is slower than passing by value? – Tim May 31 '10 at 03:53
  • 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... – M. Williams May 31 '10 at 05:50
5

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.

Philipp Claßen
  • 41,306
  • 31
  • 146
  • 239
phimuemue
  • 34,669
  • 9
  • 84
  • 115
4

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
  • 256,549
  • 94
  • 388
  • 662
  • I wonder, taking into account copy-and-swap idiom, what is the advantages not to use it (what is the advantages to use const reference) if during assignment copy will still be created (in case of const reference not immediately at call but subsequently in the body)? – uvsmtid May 03 '20 at 11:15
-2

Ok I had this problem and I couldn't find a good answer so I'm going to share what I learned.

You could pass by value there is nothing wrong with that. (as you showed in your question.)

But the reason we pass the parameter by const reference is so the function doesn't make an actual copy of the value being called in. Its referenced, so its just pointing at that value wherever it is in the memory.

This saves processing time especially if its something big that has thousands of names... In this case the time saved would be almost nothing.

And for the const, that ensures the user of the function that the referenced value is not going to be changed because it could be changed since you have access to the original location in the memory because its passed by reference.. If your function definition actually changes the value of the parameter being called in by const reference , it will be a compiler error, it wont let you do that. because when you put const, you are telling the compiler this value cannot be changed.

3366784
  • 2,423
  • 1
  • 14
  • 27
  • Consider taking discussion like this into the comments. – wizulus Feb 28 '14 at 23:05
  • What do you mean ? Sorry I'm new, I thought what I wrote was a comment. – 3366784 Mar 01 '14 at 17:37
  • A question or answer has a large number and up & down arrows on the left side. There is a link under each that says "`add comment`". Clicking that will give you a simple text box to enter a comment, like the one you just used. What you did before was enter an **answer** at the bottom of the page in a section called **"Your Answer**. Welcome to StackOverflow :) – wizulus Mar 01 '14 at 18:07
  • Ok thanks , we'll I thought what I wrote was an answer because all the other answers didn't explain why we use a const refrense they just repeated what is on refrense books. Well at least that's how I felt – 3366784 Mar 02 '14 at 05:06