C++ assignment operator, can we replace it with copy?

Viewed 498

When I was reading:

What's the difference between assignment operator and copy constructor?

here: What's the difference between assignment operator and copy constructor?

The following example was shown:

A aa;
A a = aa;  //copy constructor

vs:

A aa;
A a;
a = aa;  // assignment operator

and my question is, why we need the assignment operator at all? I mean that it will be more efficient to use the copy constructor in this case while it does the same job.

could someone give a real-world example of the use of assignment operator where that can't be replaced by the copy constructor?

4 Answers

You need assignments when you want to change a value after it has already been constructed. For example:

  • change a value that is already stored in a std::map
  • change the nth value inside a std::vector
  • change the value of a variable outside a loop
  • change the value of an output parameter provided as a pointer or reference
  • ...

The list could really go on almost endlessly. But in your example it is true that one could simply avoid the use of an assignment.

The copy constructor is called only once - at the time of initialisation of object. When the copy constructor is called, it allocates a new block of memory to the variable and then assigns it the other object .

But in assignment constructor, only the values of fields in one object are copied to the other object and the same memory is allocated when assignment constructor is called. That's the main difference between the copy constructor and assignment constructor. copy constructor allocates separate memory to both the objects, i.e. the newly created target object and the source object. The assignment operator allocates the same memory location to the newly created target object as well as the source object.

The copy constructor is called just once in object lifetime and that's if it's initialised during its declaration. Every other time you assign other object to it, the assignment constructor will be called.

Yes there is a famous one, where assignment operator cannot be replaced by copy constructor:

 std::vector <int> f();
 void g(){
     decltype(auto) v = f() = f();
     v.push_back(10); //boum undefined behaviour.
        //without the non ref qualified copy assignment operator you
        //could not have the pleasure to have undiscoverable UB in your code.
     }

Non ref qualified assignment operators and pre-increment and pre-decrement iterators operators are the best opportunities offered by the standard library to produce dangling references.

Any copy assignment could theoretically be replaced with a call to the destructor followed by a call to the copy constructor, as the constructor is not responsible for allocating the memory for the new instance. You can actually call the constructor without allocating any memory using the placement new operator.

But, the copy assignment is still interesting over the copy constructor, and your assumption that the copy constructor is more performant is false.

The big difference between copy assignment and constructor is that in assignment you can rely on the fact that the memory is already initialised. In the best case, this pre-initialisation does not offer any benefit and the copy constructor is as performant as the copy assignment. In other cases, copy assignment benefits from it and are more performant than the constructor.

And you can add the cost of the call to the destructor and the copy constructor becomes even less interesting over the assignment.

Related