What is the use of copy constructor while the same can be done with assignment operator '='?
Asked Answered
R

4

15

Why C++ provide a copy constructor? The assignment operator can do the same task. Is there any advantage of copy constructor over assignment operator?

Rathskeller answered 23/2, 2021 at 20:7 Comment(6)
How would you do Foo copy(source); without a copy constructor?Perjured
Also hard to pass by value without copy construction.Cassidycassie
@Perjured I think the OP is asking for the difference/benefit of Foo copy(source); vs Foo copy; copy = source;Doro
Copy constructor could be a deep copy, while the assignment operator could be for assigning the memory addressV2
Does this answer your question? Assignment operator Vs Copy constructorTapetum
Does this answer your question? What's the difference between assignment operator and copy constructor?Rizas
P
21

Stuff you can do with a copy constructor that you can't do (either easily or at all) with the assignment operator:

  1. Copy classes that don't have a default constructor. For example, if a class represents an open file, you might not be able to construct one without passing it a file name to open.

  2. Copy classes that have an expensive default constructor. Maybe the constructor allocates a lot of memory, which will then be released as soon as you use the assignment operator to copy a new state into the object.

  3. Pass an instance of the class by value. This is kind of the original purpose of the copy constructor. In C, if you pass a struct by value, the compiler just does a bitwise copy of the struct so the receiving function has a local copy that it can modify without affecting the caller. But C++ recognizes that a bitwise copy is not the best way to copy most objects, so it lets you write your own copy constructor (and the default copy behavior is different too, since class members may have custom copy constructors).

  4. Copy a class that contains references, because you can't reassign a reference after the class has already been constructed. The copy constructor and assignment operator just do different things where references are concerned. The copy constructor initializes the reference to point to the same object that the reference points to in the instance that is being copied; the assignment operator actually copies the value of the referenced object.

  5. Copy a class with const members. (Note that a class can have a default constructor but still have const members.)

Payday answered 23/2, 2021 at 20:27 Comment(4)
Re point 4, isn't it a bad idea for a class that copy-constructs by reference to also be copy-assignable?Aircrew
Probably. I’m trying to think of an example in which you’d want to do that and not really coming up with anything.Payday
Re 2: You dropped an "efficiently" there, because it is certainly possible though wasteful.Sisto
I tried to cover that with the "either easily or not at all" comment. It's also possible to assign classes with const members (#5) by casting the const away, or allocate an object without calling its constructor and then assign over it. It's just not a good idea.Payday
D
11

With or without a copy constructor, you still have to initialize a new object to a stable initial state, which the assignment operator can then update later.

While you can certainly do that without a copy constructor, having a copy constructor helps to optimize a new object's initialization, by setting it to copy another object's state up front, without requiring you to first initialize the new object to a default state and then have a separate assignment reset that state afterwards. This way, you can set the new object's state in 1 operation instead of 2 operations.

Doro answered 23/2, 2021 at 20:11 Comment(0)
B
4

Yes, the two are different. You can't always just implement your copy constructor as

Foo(const Foo& f) {
    *this = f;
}

The assignment operator assumes that you have a valid, fully constructed object. The copy constructor makes no such assumptions. This means that, depending on your class, the assignment operator may try to clear whatever data is on the object before re-initializing. Or may even repurpose the data already on the object.

Bistoury answered 23/2, 2021 at 20:11 Comment(5)
Typically, one should implement the assignment operator to use the copy constructor, not the other way around.Doro
Absolutely @Remy. Might be work mentioning the Copy Swap idiom here actually.Bistoury
@RemyLebeau, what if the class is abstract and I don't want to move implementation into derived classes?Chucklehead
An abstract class can still have constructors and assignment operators, which derived classes can call as needed.Doro
@RemyLebeau If I want to put all copy construction code into the base class that already has an assignment operator, I can use *this = f; type of constructor. However, I can't implement assignment via copy construction. The question is whether this problem has some idiomatic solution.Chucklehead
C
-1

Take this example.

Jack and John are twins. You could say this is Jack and that is Jack. But although John is the spitting image of Jack, he ain't no Jack.

When you use the assignment operator you can refer to the exact object in memory (returning *this) or provide some custom behavior.

When you use the copy constructor you want to create another object in memory that has a copy of the properties of the original object, but that can evolve in a different direction.

If you want a deeper answer I think this blog post is better.

Assignment is a little more tricky than initialization, because what we are essentially doing is destructing the existing object and then re-constructing it with new values. In a more complex class, you might need to free various resources and then re-allocate them using copies of the resources from the object being copied. std::unique_ptr makes our life easy here, because assigning a new instance of std::unique_ptr to an existing std::unique_ptr object with = as above (or by using reset()) first frees the old pointer, so releasing the resource is handled for us automatically (this is the same reason our class doesn’t need a destructor – when std::unique_ptr goes out of scope as our object goes out of scope, std::unique_ptr‘s destructor is called and the resource is freed automatically).

Cozenage answered 24/2, 2021 at 14:55 Comment(2)
This isn't true in C++ about the assignment operator: "exact object in memory", "two variables that point to the same memory block".Aminoplast
Looks like it's been too long from my C++ days. I found this comparison interesting copy-constructor-vs-assignment-operator-in-cChow

© 2022 - 2024 — McMap. All rights reserved.