Remix.run Logo
jayd16 a day ago

https://en.cppreference.com/w/cpp/language/copy_constructor....

> For non-union class types, the constructor performs full member-wise copy of the object's direct base subobjects and member subobjects, in their initialization order, using direct initialization. For each non-static data member of a reference type, the copy constructor binds the reference to the same object or function to which the source reference is bound.

Would you call this deep or shallow? I think most would call it a shallow copy.

HarHarVeryFunny 12 hours ago | parent [-]

The default copy constructor does a member-wise copy, but that member-wise copy in turn uses each member's copy constructor (explicit or default), if it has one.

So for example, if your class has members whose type is any of the STL container types (std::list, vector, map, set,etc) then you will get a deep copy since that is how those types behave.

The semantics of a reference as part of a class are whatever you choose to make them. Is the reference referring to something within the class, maybe initialized in the constructor, or is it referring to something external such as a global variable perhaps? It's up to you to define your constructors according to the semantics of how you are using the reference. If you don't provide a copy constructor then the default member-wise copy would indeed just make a copy of the reference, which would be the right thing if you were using the reference to point to something global, but would be a bug in your code (missing copy constructor) if you needed it to refer to something in the copied class.

Raw pointers in classes are much the same. How are you using the pointer, and what does that mean that your copy constructor needs to do? Just like with the reference example, the default member-wise copy will only be correct if you are using the pointer to point to something not owned by the containing class, and just want the copy to point to the same thing. If the pointer is an owning reference to something allocated on the heap, then maybe you would want the copy to allocate it's own storage and copy the contents, but only you would know that.

The semantics of smart pointers are more clear cut, which is why they are to be preferred in modern C++ code. A std::unique_ptr simply can't be copied, so you would be forced to write a copy constructor to handle it. The default member-wise copy of a std::shared_ptr will just invoke it's copy constructor resulting in the copy pointing to the same object, now with an increased reference count.

Long story short, if you are writing modern C++, using STL container types, then a copy is a deep copy. If you are writing your own container types using pointers, or implementing your own copy constructors, then "copy" means whatever you have chosen it to mean.