Search code examples
c++compiler-constructionshallow-copy

C++ compiler 'shallow' copies and assignments


I'm taking a class on object oriented programming using C++.

In our text it says,

If we do not declare a copy constructor, the compiler inserts code that implements a shallow copy. If we do not declare an assignment operator, the compiler inserts code that implements a shallow assignment.

What I want to know, is whether this is in fact true, what the alluded to compiler mechanism is actually called, and how it works.

This is not a question about copy constructors, it is about compiler behavior.

EDIT> More context

Copy Constructor as defined by the text:

The definition of a copy constructor contains logic that

  1. performs a shallow copy on all of the non-resource instance variables
  2. allocates memory for each new resource
  3. copies data from the source resource(s) to the newly created resource(s)

Resource as defined by the text

Memory that an object allocates at run-time represents a resource of that object's class.

The management of this resource requires additional logic that was unnecessary for simpler classes that do not access resources. This additional logic ensures proper handling of the resource and is often called deep copying and assignment.


Solution

  • It's more accurate to say that the compiler defines a default copy constructor and a default copy assignment operator. These will copy/construct the new object by simply calling the copy constructor for all of the member variables.

    • For primitives like ints and floats, this usually isn't a problem.
    • For pointers, though. This is bad news! What happens when the first object deletes that pointer? Now the other object's pointer is invalid!
    • If a member variable cannot be copied (perhaps you used a std::unique_ptr to fix the above problem), then the default copy assignment/ctor won't work. How can you copy something that can't be copied? This will lead to a compiler error.

    If you define your own copy constructor/assignment operator, you can make a "deep copy" instead. You can:

    • Create a new object, rather than copying the pointer
    • Explicitly "shallow copy" a pointer
    • Mix the above two based on what you actually want!
    • Initialize member variables with default/custom values in copied objects rather than copy whatever was in the original object.
    • Disable copying altogether
    • On and on and on

    As you can see, there are plenty of reasons why you'd want to implement (or explicitly prohibit) your own copy assignment operator, copy constructor, their move counterparts, and destructor. In fact, there's a well-known C++ idiom known as The Rule of Five (formerly the Rule of 3) that can guide your decision on when to do this.