0

Why when let's say I have an object declared like this: Obj o1; which is initialized by the default constructor (not very important here, how was o1 initialized, the point is it was initialized) and I create another object in this manner: Obj o2 = o1; the copy constructor is implicitly called, but if I delete the copy constructor, then, I get a compile error. Why the object o1 is not assigned/copied to o2, like here: Obj o1; Obj o2; o2 = o1;? Why the compiler tries to call a constructor in any instance? Is the = operator within Obj o2 = o1; overloaded?

pauk
  • 350
  • 4
  • 15
  • 2
    *The equals sign, =, in copy-initialization of a named variable is not related to the assignment operator. Assignment operator overloads have no effect on copy-initialization.* [cppreference](https://en.cppreference.com/w/cpp/language/copy_initialization) – alex_noname Nov 08 '21 at 08:54
  • 1
    Assignment operator assumes the left side already exists. – Quimby Nov 08 '21 at 08:55
  • Copy-initialization might *elide* calling the copy-constructor, but the copy-constructor must still be available (i.e. not deleted) for it to be possible to copy the object. – Some programmer dude Nov 08 '21 at 08:56
  • Many symbols in C++ mean diffferent things in different contexts. `=` is one of them. – molbdnilo Nov 08 '21 at 08:57

1 Answers1

3

As mentioned in comments, this

Obj o2 = o1;

has nothing to do with assignment. It is a little unfortunate, often confusing, use of = for initialization when otherwise = means assignment.

Also mentioned in comments, the operator= has to assume that the left operator already exists. Consider this somewhat contrived example:

#include <vector>

struct my_vect {
    my_vect() : data(2) {}
    my_vect(const my_vect& other) : data(other.data) {}
    my_vect& operator=(my_vect& other) {
        // this has already been constructed,
        // hence data.size() is 2 already
        data[0] = other.data[0];
        data[1] = other.data[1];
        return *this;
    }
private:
    std::vector<int> data;
};

It is a structure that contains a std::vector whose size is always 2. The vector is initialized upon constructing a my_vect. When assigning one my_vect to another, then data needs not be initialized. Only the values must be copied. Because operator= assumes that the left hand side operator is already properly constructed (it merely copies to data[0] and data[1]) it cannot possibly be used to construct an object (in the example, accessing data[0] or data[1] would be out of bounds).

TL;DR: Constructors construct objects. Assignment assigns to an already existing object. Thats two fundamentally different things.

G. Sliepen
  • 7,637
  • 1
  • 15
  • 31
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • Yes, but here I have ``Obj o1 = o2;``, and ``Obj o1;`` is enough for initializing the object, as long as the default constructor is called, thus I expected ``Obj o1 = o2;`` to be executed as ``Obj o1; o1 = o2;`` as long as no copy constructor is provided. – pauk Nov 08 '21 at 11:12
  • But for this two instructions had to be executed, separately. – pauk Nov 08 '21 at 11:19
  • @pauk this could be happen, but thats just not how C++ works. In general default construction plus subsequent assignment is more expensive than only copy construction, hence it is good that in C++ you have to explicitly ask for it when you want it. I mean nothing prevents you from writing `Obj o1; o1 = o2;` when that is what you want – 463035818_is_not_an_ai Nov 08 '21 at 11:56