61

Possible Duplicate:
What is the difference between a deep copy and a shallow copy?

What is the difference between deep and shallow copy. What type of a copy does a copy constructor do?

Community
  • 1
  • 1
Ankur
  • 1,189
  • 4
  • 12
  • 12
  • 3
    Duplicate of http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy – Srinivas Reddy Thatiparthy Apr 17 '10 at 08:51
  • 1
    1st question is a dup, but I can't find the 2nd, though that could be because it isn't stated clearly. @Ankur: in your second question, are you asking about the default copy constructor? – outis Apr 17 '10 at 09:31
  • 1
    The terms deep vs shallow copy aren't typically used in C++, since they don't map particularly well to the language. In Java and several other languages, the distinction is more useful because of their reference-based semantics, making shallow copy unavoidable in most cases. In C++, where objects are copied by value, true shallow copies are very rare, but the default copy constructor won't implement a deep copy either. The terms just don't make sense in C++ – jalf Apr 17 '10 at 11:56

3 Answers3

61

Shallow copy:

Some members of the copy may reference the same objects as the original:

class X
{
private:
    int i;
    int *pi;
public:
    X()
        : pi(new int)
    { }
    X(const X& copy)   // <-- copy ctor
        : i(copy.i), pi(copy.pi)
    { }
};

Here, the pi member of the original and copied X object will both point to the same int.


Deep copy:

All members of the original are cloned (recursively, if necessary). There are no shared objects:

class X
{
private:
    int i;
    int *pi;
public:
    X()
        : pi(new int)
    { }
    X(const X& copy)   // <-- copy ctor
        : i(copy.i), pi(new int(*copy.pi))  // <-- note this line in particular!
    { }
};

Here, the pi member of the original and copied X object will point to different int objects, but both of these have the same value.


The default copy constructor (which is automatically provided if you don't provide one yourself) creates only shallow copies.

Correction: Several comments below have correctly pointed out that it is wrong to say that the default copy constructor always performs a shallow copy (or a deep copy, for that matter). Whether a type's copy constructor creates a shallow copy, or deep copy, or something in-between the two, depends on the combination of each member's copy behaviour; a member's type's copy constructor can be made to do whatever it wants, after all.

Here's what section 12.8, paragraph 8 of the 1998 C++ standard says about the above code examples:

The implicitly defined copy constructor for class X performs a memberwise copy of its subobjects. [...] Each subobject is copied in the manner appropriate to its type: [...] [I]f the subobject is of scalar type, the builtin assignment operator is used.

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
  • 1
    The cryptic paragraph seems to disagree with your bold claim that default copy constructor only makes shallow copies. – UncleBens Apr 17 '10 at 09:37
  • What makes you think so? I understand this as follows: Members of some pointer type are a scalar subobject, aren't they? And if you copy a pointer using the inbuilt assignment operator, that means that the pointed-to object won't be cloned, but simply be referred to by an additional pointer. Therefore you end up with a shallow copy. – stakx - no longer contributing Apr 17 '10 at 09:52
  • 1
    @stakx You are right, but I think this illustrates that the terms "deep copy" and "shallow copy" are not particularly useful - in fact I've never heard them used by experienced C++ programmers. –  Apr 17 '10 at 10:45
  • 2
    The default copy constructor makes a *member-wise* copy, and whether a deep or shallow copy is made of a member depends entirely on the behavior of members. `struct Person { string firstName, lastName; }` - the default copy constructor makes a *deep* copy. – UncleBens Apr 17 '10 at 10:53
  • @UncleBens: No it doesn't. Not if one of the members is a pointer or reference type. So as @Neil said, the terms just aren't useful in C++. Even in fairly simple cases, the default copy constructor will do some in-between thing, as will many user-defined copy constructors. – jalf Apr 17 '10 at 11:58
  • 1
    The set of all possible Copy contructor "types" does not include the disjoint set of JUST "shallow" and "deep". It includes everything in-between (e.g. half the members may be shallow copied, half may be deep copied - yet you'll never know if THOSE members are doing a shallow or deep copy unless you know THEIR implementations). The default copy constructor is neither always "shallow" nor always "deep". The terms shallow and deep just describe possible behaviors. – franji1 Aug 01 '10 at 20:13
  • How about: default object copy constructor does a deep copy but a pointer type's copy constructor does a shallow copy. – Stephen Cross Nov 18 '16 at 21:26
16

The quintessential example of this is an array of pointers to structs or objects (that are mutable).

A shallow copy copies the array and maintains references to the original objects.

A deep copy will copy (clone) the objects too so they bear no relation to the original. Implicit in this is that the object themselves are deep copied. This is where it gets hard because there's no real way to know if something was deep copied or not.

The copy constructor is used to initilize the new object with the previously created object of the same class. By default compiler wrote a shallow copy. Shallow copy works fine when dynamic memory allocation is not involved because when dynamic memory allocation is involved then both objects will points towards the same memory location in a heap, Therefore to remove this problem we wrote deep copy so both objects have their own copy of attributes in a memory.

In order to read the details with complete examples and explanations you could see the article Constructors and destructors.

The default copy constructor is shallow. You can make your own copy constructors deep or shallow, as appropriate. See C++ Notes: OOP: Copy Constructors.

royal52
  • 29
  • 4
cletus
  • 616,129
  • 168
  • 910
  • 942
4

Deep copy literally performs a deep copy. It means, that if your class has some fields that are references, their values will be copied, not references themselves. If, for example you have two instances of a class, A & B with fields of reference type, and perform a deep copy, changing a value of that field in A won't affect a value in B. And vise-versa. Things are different with shallow copy, because only references are copied, therefore, changing this field in a copied object would affect the original object.

What type of a copy does a copy constructor does?

It is implementation - dependent. This means that there are no strict rules about that, you can implement it like a deep copy or shallow copy, however as far as i know it is a common practice to implement a deep copy in a copy constructor. A default copy constructor performs a shallow copy though.

n535
  • 4,983
  • 4
  • 23
  • 28