1

The return type will be different of course, but the concept is the same: copying the data from one object to another, right?

Pelle
  • 11
  • 1
  • The difference is that the assignment operator can assume the object being assigned is initialised, and has to clean it up correctly, whereas the copy constructor cannot assume the object being constructed is initialised, so does not need to clean it up. Practically, It is often better to implement one in terms of the other, not to replicate the same code in both. For example, implement the assignment operator using the copy constructor. – Peter Oct 14 '19 at 09:07
  • Not the same, but probably helpful: https://stackoverflow.com/questions/17480396/call-copy-constructor-from-assignment-operator-function – stefaanv Oct 14 '19 at 09:08
  • 1
    It's good idea to use the [copy and swap idiom](https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) – Yksisarvinen Oct 14 '19 at 09:10
  • 2
    @Yksisarvinen I would say that it's a good idea to _consider_ copy and swap idiom. It's not always the optimal solution. For instance, for vectors, C&S would always allocate new memory, which might be unnecessary if the _capacity of the assigned-to vector_ is less or equal to the _size of the assigned-from vector_. The same holds for strings. – Daniel Langr Oct 14 '19 at 10:01
  • @DanielLangr You're right. Your example would make a good answer, as a counterproof to OP's statement that these two operations are the same. – Yksisarvinen Oct 14 '19 at 10:06

3 Answers3

5

The concepts are fundamentally different; the copy constructor creates a new object where one doesn’t exist (and does not return anything – not even void), and the assignment operator updates an object that already exists.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
3

No. While the copy assignment operator does copy data to another object, the copy constructor initializes a new object with the copied data. As such, it will use its member initializer list to invoke its member's copy constructors recursively, while the copy-assignment operator will invoke other copy-assignment operators.

struct Foo {

    Foo(Foo const &orig)
    : data{oring.data} { }

    Foo &operator = (Foo const &orig) {
        data = orig.data;
        return *this;
    }

private:
    std::string data;
};
Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Perhaps checking that `&orig != this` to avoid auto-assignment could be better :) – Fareanor Oct 14 '19 at 09:20
  • 2
    @Fareanor that's a bit [contentious](https://stackoverflow.com/q/12015156/3233393) though. In this case, I trust `std::string`'s assignment operator to work correctly without me checking. – Quentin Oct 14 '19 at 09:23
  • If the 'data' were pointers, would this code still work? In that case it would have looked like this: Foo(Foo const &orig) { data = new int; *data = *(orig.data); } Foo &operator = (Foo const &orig) { delete data; data = new int; *data = *(orig.data) return *this; This kinda looks the same... – Pelle Oct 14 '19 at 09:56
  • @Pelle if the data were pointers, then you'd need to do a deep copy; use a shared_ptr or protect the data from double deletes in some other way – UKMonkey Oct 14 '19 at 09:59
  • @Pelle raw owning pointers shouldn't be used anyway, so you don't need the explicit `delete`. – Quentin Oct 14 '19 at 11:18
0

The copy constructor initializes the new object with an already existing object.

The copy assignment assigns the value of one object to another object both of which are already in existence.

Ganesa Vijayakumar
  • 2,422
  • 5
  • 28
  • 41