What's the Difference Between Assignment Operator and Copy Constructor

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

A copy constructor is used to initialize a previously uninitialized object from some other object's data.

A(const A& rhs) : data_(rhs.data_) {}

For example:

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

An assignment operator is used to replace the data of a previously initialized object with some other object's data.

A& operator=(const A& rhs) {data_ = rhs.data_; return *this;}

For example:

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

You could replace copy construction by default construction plus assignment, but that would be less efficient.

(As a side note: My implementations above are exactly the ones the compiler grants you for free, so it would not make much sense to implement them manually. If you have one of these two, it's likely that you are manually managing some resource. In that case, per The Rule of Three, you'll very likely also need the other one plus a destructor.)

difference between copy constructor and assignment operator

Other than what you said, there is no difference.

The CC works on new unitizialied objects (it´s a constructor after all), the operator on existing ones.

The use of the CC could be replaced with the normal constructor and then the assignment op (in usual classes), but this would be not as efficient as the direct construction with copied data.

Eg.

class C
{
private:
vector<int> v;
public
C()
{
//fill v with 10^9 slowly generated random numbers, takes ca. 2 days
}
C(const C& c) //could be auto-generated in this case
{
v = c.v;
}
C &operator=(const C& c) //could be auto-generated in this case
{
v = c.v;
return *this;
}
};

...

C oldc;

...

//either
C newc(oldc);
//or
C newc; //takes 2 days
newc = oldc;

Another reason, some nontrivial classes have no (public) default constructor and can only be created by copying existing objects from somewhere.

copy constructor and assignment operator in C++

Constructors, including copy constructors, are for initializing a class object. Assignment operators are for modifying an object which was already initialized.

Line (1) calls a copy constructor because it is initializing the object second. The assignment operator has nothing to do with the fact that the = symbol is also used in this syntax. Line (2) assigns to first which already exists, so uses the assignment operator.

In C++14 and earlier for line (3), the compiler is allowed to create a temporary object for the MyClass(2) expression, then use the copy constructor to initialize third, then destroy the temporary. But the compiler is also allowed to "elide" (remove) the temporary object, the copy constructor, and the temporary destructor, just initializing third directly in the same way as the original temporary. This copy elision is the one case where C++ allows an optimization which can cause a difference in observable behavior, since the copy constructor and/or destructor might have side effects (like printing traces) which the optimization skips.

In C++17 and later for line (3), we say that the expression MyClass(2) has result object third. So the expression specifies that third is direct-initialized with argument 2. No copy constructor or temporary object is involved. This feature of C++17 is often called "mandatory copy elision", since the behavior is the same as a C++14 program where the compiler was able to apply the copy elision optimization. But technically it's not a copy elision, since there is no copy involved to elide. There are still some other cases where copy elision is optional for the compiler.

Copy constructor vs assignment operator with STL vector

Is there any way a vector can be declared and instantiated while skipping the copying operation?

No. When you do vector<A> obj {1,2,3} the compiler creates a std::initializer_list<A> from the values provided. That std::initializer_list creation is the reason you see the three normal constructor calls. The vector then has to copy those elements because the underlying storage for those elements is const. There is no was to get around that with list initialization. Even vector<A> obj {A(1),A(2),A(3)} would still cause copies.

If you don't want that then one thing you can do is create storage for the elements using reserve, and then use emplace_back to directly construct the objects in the vector like

vector<A> obj;
obj.reserve(3);
for (int i = 1; i < 4, ++i)
obj.emplace_back(i);

Doing obj_1 = obj, if my obj_1 was previously initialized results in calling the copy constructor instead of operator= function inside my class A as I was expecting?

This is because obj_1 is empty. Since it is empty, there is no element to call the assignment operator on. Instead what it does is create elements in obj_1 that are copies of obj and the most efficient way to do that is to just call the copy constructor instead of default constructing the objects and then assigning to them.

If you had

vector<A> obj {1,2,3};
vector<A> obj_1 {3, 4, 5};
obj_1 = obj;

Instead then you would see the assignment operator be used instead since there are objects to actually assign to.

The copy constructor and assignment operator

No, they are different operators.

The copy constructor is for creating a new object. It copies an existing object to a newly constructed object.The copy constructor is used to initialize a new instance from an old
instance. It is not necessarily called when passing variables by value into functions
or as return values out of functions.

The assignment operator is to deal with an already existing object. The assignment operator is used to change an existing instance to have
the same values as the rvalue, which means that the instance has to be
destroyed and re-initialized if it has internal dynamic memory.

Useful link :

  • Copy Constructors, Assignment Operators, and More
  • Copy constructor and = operator overload in C++: is a common function possible?

Why not only one? Copy constructor and assignment operator

No, they are different.

Copy constructor is used for constructing a new object (from another object). In this case you just need to initialize the members.

Assignment operator is used for an existing object (you may have constructed it by default constructor etc), and then assign it by another object. In this case you need to re-initialize members, sometimes means destroying and initializing them again.

Even so, the functionality of them are so similar, so you can share their implementation usually. Such as: What is the copy-and-swap idiom?



Related Topics



Leave a reply



Submit