473,398 Members | 2,404 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Deep versus Shallow Copy - Part 1

I have decided (see earlier post) to paste my Word doc here so that it
will be simpler for people to provide feedback (by directly inserting
their comments in the post). I will post it in 3 parts to make it more
manageable.

Below is a draft of a document that I plan to give to my introductory
C++ class.

Please note that I have purposely left out any mention of safety issues
in the ctors which could be resolved thru some combination smart
pointers or exception handling. These topics will be introduced in the
follow up course.

If anyone would like the complete document in MS Word (after I have
incorporated improvements you folks suggest), send me an e-mail with
"Deep versus Shallow Copy" as a title. The appearance in the Word doc
is much better (this tool is rather limited when it comes to formatting
choices and it seems to get the indentation wrong when translating from
Word).

PART 1:

Subject: Explanation of Deep versus Shallow Copy
Author: Bob Langelaan
Date: Nov. 25th, 2006

Note: The reader should already have studied the following C++
concepts in order to be able to understand this document: pointers and
references; the "new" and "delete" operators; the member
initialization list (MIL); the "this" pointer.

1.0 Introduction

Let us start with the following class:

class Example1
{
private:
int ii;
double dd;
ABC abc;
};

Now let us instantiate several Example1 objects:

Example1 xyz1, xyz2;
..
.. // Assume xyz1's value modified here
..
xyz2 = xyz1; // Is this allowed?

Yes, the above program statement is allowed in C++. The assignment
operator is normally automatically overloaded (see section "3.0
Advanced Topic Addendum" below for details on some exceptions) for
any class in C++. If the programmer does not overload the assignment
operator, the compiler will do it for you. Let us assume that in this
case the programmer has not explicitly overloaded the assignment
operator. What will the compiler supplied assignment operator
(sometimes called the "implicit" or "synthesized" assignment
operator) do in the statement above?

The ii member of xyz1 will be assigned to the ii member of xyz2; the dd
member of xyz1 will be assigned to the dd member of xyz2; and the abc
member of xyz1 will be assigned to the abc member of xyz2. This
process of assigning the members of one object to the members of
another object is called a "memberwise" assignment. Programmers
may also refer to this as a "shallow copy".

What if we have the following C++ statement?

Example1 xyz3 = xyz1; // Does this invoke the overloaded
// assignment operator as well?

No. In this case the copy constructor of the Example1 class will be
invoked. Just as with the overloaded assignment operator, if the
programmer does not supply a copy constructor for their class, the
compiler will. The compiler supplied copy constructor (the implicit or
synthesized copy constructor) does the equivalent to initializing all
of the members of the new object in its member initialization list
(MIL). This, in turn, will cause the copy constructor for each of the
members to be invoked. Therefore, in the previous C++ statement, the
compiler supplied copy constructor will effectively invoke the copy
constructor for each of the members of xyz3, passing to each copy
constructor the corresponding member of xyz1.

But what if we having the following class:

class Example2
{
public:
Example2();
private:
int ii;
double dd;
ABC * abcPtr; // will point to a dynamically created ABC object
};

And here is the implementation of the Example2 constructor:

Example2::Example2()
{
abcPtr = new ABC; // dynamically create an ABC object
// and have the class member abcPtr point to it.
Nov 26 '06 #1
13 4975
On 2006-11-26 19:39, blangela wrote:
What if we have the following?

Example2 xyz3 = xyz1; // Can we use the compiler
// supplied copy constructor here?

No. The compiler supplied copy constructor will do a shallow copy. It
will effectively do this:

xyz3.abcPtr = xyz1.abcPtr; // this simply assigns one pointer
// to the other pointer

when what we need it to effectively do is:

xyz3.abcPtr = new ABC; // first dynamically create an ABC object
// (remember that xyz3 is constructed in this copy constructor)
*(xyz3.abcPtr) = *(xyz1.abcPtr); // then do the same as the
// programmer supplied assignment operator - a deep copy

Unless you have some pedagogical reason not to wouldn't it be better
with something like this:

xyz3.abcPtr = new ABC(*(xyz1.abcPtr)); // Copy-create a new ABC object

Of course, since you expect the reader to be familiar with
initialization, it would be even better to use initialization in the
examples:

Example2::Example2(Example2& e)
: abcPtr(new ABS(*(e.abcPtr))
{
}

It's a bit late here so there are probably some errors in the above but
I think you'll get the idea.

--
Erik Wikström
Nov 26 '06 #2

Erik Wikström wrote:
On 2006-11-26 19:39, blangela wrote:
What if we have the following?

Example2 xyz3 = xyz1; // Can we use the compiler
// supplied copy constructor here?

No. The compiler supplied copy constructor will do a shallow copy. It
will effectively do this:

xyz3.abcPtr = xyz1.abcPtr; // this simply assigns one pointer
// to the other pointer

when what we need it to effectively do is:

xyz3.abcPtr = new ABC; // first dynamically create an ABC object
// (remember that xyz3 is constructed in this copy constructor)
*(xyz3.abcPtr) = *(xyz1.abcPtr); // then do the same as the
// programmer supplied assignment operator - a deep copy


Unless you have some pedagogical reason not to wouldn't it be better
with something like this:

xyz3.abcPtr = new ABC(*(xyz1.abcPtr)); // Copy-create a new ABC object

Of course, since you expect the reader to be familiar with
initialization, it would be even better to use initialization in the
examples:

Example2::Example2(Example2& e)
: abcPtr(new ABS(*(e.abcPtr))
{
}

It's a bit late here so there are probably some errors in the above but
I think you'll get the idea.

--
Erik Wikström
My students are still getting comfortable with pointers, MILs and the
new operator, so doing it the way I have shown makes the code easier to
understand. Otherwise, I agree with your suggestions.

Bob

Nov 26 '06 #3
blangela wrote:
I have decided (see earlier post) to paste my Word doc here so that it
will be simpler for people to provide feedback (by directly inserting
their comments in the post). I will post it in 3 parts to make it more
manageable.

Below is a draft of a document that I plan to give to my introductory
C++ class.

Please note that I have purposely left out any mention of safety issues
in the ctors which could be resolved thru some combination smart
pointers or exception handling. These topics will be introduced in the
follow up course.

If anyone would like the complete document in MS Word (after I have
incorporated improvements you folks suggest), send me an e-mail with
"Deep versus Shallow Copy" as a title. The appearance in the Word doc
is much better (this tool is rather limited when it comes to formatting
choices and it seems to get the indentation wrong when translating from
Word).

PART 1:

Subject: Explanation of Deep versus Shallow Copy
Author: Bob Langelaan
Date: Nov. 25th, 2006

Note: The reader should already have studied the following C++
concepts in order to be able to understand this document: pointers and
references; the "new" and "delete" operators; the member
initialization list (MIL); the "this" pointer.

1.0 Introduction

Let us start with the following class:

class Example1
{
private:
int ii;
double dd;
ABC abc;
};
I think the paper would be improved by using a more meaningful class
than "Example1" as the example. After all, if the example appears to be
contrived, then the student may question the relevancy of the material.
So the more "realistic" the example provided, the more likely that a
student will be able to apply it to C++ code they see and to the C++
code that they write. The specific class chosen does not matter all
that much: a "Shape" class, or a "Vehicle" class, or even a "String"
class are some of the usual choices.

Another important programming lesson is to choose the names of
identifiers carefully. Well-chosen names document the program and
minimize the likelihood of making a mistake. For that reason, this
program is not setting a good example by having identifiers with names
that differ only by one character at the very end of the name.
"Example1" and "Example2" (besides not communicating what either class
actually represents) may suggest that class names should resemble each
other as much as possible - when in fact the goal is the opposite.
Because the last thing that a programmer wants is to have two classes
whose names are easy to mix up.

Greg

Nov 27 '06 #4

Greg wrote:
blangela wrote:
I have decided (see earlier post) to paste my Word doc here so that it
will be simpler for people to provide feedback (by directly inserting
their comments in the post). I will post it in 3 parts to make it more
manageable.

Below is a draft of a document that I plan to give to my introductory
C++ class.

Please note that I have purposely left out any mention of safety issues
in the ctors which could be resolved thru some combination smart
pointers or exception handling. These topics will be introduced in the
follow up course.

If anyone would like the complete document in MS Word (after I have
incorporated improvements you folks suggest), send me an e-mail with
"Deep versus Shallow Copy" as a title. The appearance in the Word doc
is much better (this tool is rather limited when it comes to formatting
choices and it seems to get the indentation wrong when translating from
Word).

PART 1:

Subject: Explanation of Deep versus Shallow Copy
Author: Bob Langelaan
Date: Nov. 25th, 2006

Note: The reader should already have studied the following C++
concepts in order to be able to understand this document: pointers and
references; the "new" and "delete" operators; the member
initialization list (MIL); the "this" pointer.

1.0 Introduction

Let us start with the following class:

class Example1
{
private:
int ii;
double dd;
ABC abc;
};

I think the paper would be improved by using a more meaningful class
than "Example1" as the example. After all, if the example appears to be
contrived, then the student may question the relevancy of the material.
So the more "realistic" the example provided, the more likely that a
student will be able to apply it to C++ code they see and to the C++
code that they write. The specific class chosen does not matter all
that much: a "Shape" class, or a "Vehicle" class, or even a "String"
class are some of the usual choices.

Another important programming lesson is to choose the names of
identifiers carefully. Well-chosen names document the program and
minimize the likelihood of making a mistake. For that reason, this
program is not setting a good example by having identifiers with names
that differ only by one character at the very end of the name.
"Example1" and "Example2" (besides not communicating what either class
actually represents) may suggest that class names should resemble each
other as much as possible - when in fact the goal is the opposite.
Because the last thing that a programmer wants is to have two classes
whose names are easy to mix up.

Greg
Thanks for your input - Bob.

Nov 27 '06 #5
blangela wrote:
Below is a draft of a document that I plan to give to my introductory
C++ class.

Subject: Explanation of Deep versus Shallow Copy
Personally, I find the terms "shallow copy" and "deep copy"
confusing w.r.t. C++, and I'm glad my learning resources
never mentioned them.

The reality is that when you copy an object using the
default assignment operator or copy constructor, you get
an exact replica of the original. If the original had a handle
on a resource (eg. pointer to memory) then the copy will
have another handle on that same resource.

This is a very simple concept (to me, anyway) and does
not need to be obfuscated with discussions about "deep"
and "shallow". The term "shallow copy" can imply that
if an object contains another object, then the sub-object
won't be copied -- which is not true.

If it were me teaching, the point I would be making is
that if you want to allocate new resources when
copying an object, you are going to need a user-defined
assignment operator & copy constructor.

BTW I don't think it's correct to talk about the default
assignment operator as being an "overload" -- not sure
on that though.

Nov 27 '06 #6
Old Wolf <ol*****@inspire.net.nzwrote:
>Personally, I find the terms "shallow copy" and "deep copy"
confusing w.r.t. C++, and I'm glad my learning resources
never mentioned them.
>The reality is that when you copy an object using the
default assignment operator or copy constructor, you get
an exact replica of the original. If the original had a handle
on a resource (eg. pointer to memory) then the copy will
have another handle on that same resource.
>This is a very simple concept (to me, anyway) and does
not need to be obfuscated with discussions about "deep"
and "shallow". The term "shallow copy" can imply that
if an object contains another object, then the sub-object
won't be copied -- which is not true.
I totally agree. "Shallow copy" means the same thing as
simply "copy". "Deep copy" means you have an algorithm that
descends (at least some) indirect references and makes
duplicates. "Deep copies" involve procedural code that
is situation specific, and saying "this makes a deep copy"
is in general ambiguous.

Steve
Nov 27 '06 #7

Steve Pope wrote:
Old Wolf <ol*****@inspire.net.nzwrote:
Personally, I find the terms "shallow copy" and "deep copy"
confusing w.r.t. C++, and I'm glad my learning resources
never mentioned them.
The reality is that when you copy an object using the
default assignment operator or copy constructor, you get
an exact replica of the original. If the original had a handle
on a resource (eg. pointer to memory) then the copy will
have another handle on that same resource.
This is a very simple concept (to me, anyway) and does
not need to be obfuscated with discussions about "deep"
and "shallow". The term "shallow copy" can imply that
if an object contains another object, then the sub-object
won't be copied -- which is not true.

I totally agree. "Shallow copy" means the same thing as
simply "copy". "Deep copy" means you have an algorithm that
descends (at least some) indirect references and makes
duplicates. "Deep copies" involve procedural code that
is situation specific, and saying "this makes a deep copy"
is in general ambiguous.

Steve
A shallow copy is a member-wise copy. A deep copy is anything other
than a shallow copy. What could be simpler than that?

Nov 27 '06 #8
blangela <Bo***********@telus.netwrote:
>Steve Pope wrote:
>Old Wolf <ol*****@inspire.net.nzwrote:
>Personally, I find the terms "shallow copy" and "deep copy"
confusing w.r.t. C++, and I'm glad my learning resources
never mentioned them.
>The reality is that when you copy an object using the
default assignment operator or copy constructor, you get
an exact replica of the original. If the original had a handle
on a resource (eg. pointer to memory) then the copy will
have another handle on that same resource.
>This is a very simple concept (to me, anyway) and does
not need to be obfuscated with discussions about "deep"
and "shallow". The term "shallow copy" can imply that
if an object contains another object, then the sub-object
won't be copied -- which is not true.
>I totally agree. "Shallow copy" means the same thing as
simply "copy". "Deep copy" means you have an algorithm that
descends (at least some) indirect references and makes
duplicates. "Deep copies" involve procedural code that
is situation specific, and saying "this makes a deep copy"
is in general ambiguous.
>A shallow copy is a member-wise copy. A deep copy is anything other
than a shallow copy. What could be simpler than that?
It's simple, but it also makes the definition of "deep copy"
so broad as to be fairly useless.

Steve
Nov 27 '06 #9
blangela wrote:
>
A shallow copy is a member-wise copy. A deep copy is anything other
than a shallow copy. What could be simpler than that?
Firstly, if that is your definition then why not just call them
what they are: "member-wise copy" and "non member-wise copy" ?

Second, that's not the commonly accepted definition of
'shallow copy' and 'deep copy' in computer science, so
it is confusing. Look at this example, where Foo is some class:

// C++:
class S { public: Foo foo; };

// Java:
class S { public Foo foo; };

In Java, assigning an object of type S to another object of type S
results in both objects having a handle on a single shared instance
of Foo. I think we would agree that this is a shallow copy.

In C++, the same assignment results in both objects having their
own Foo objects (so there are now two Foos in existence).

Now, you are trying to say that the C++ behaviour is a "shallow copy".
It is clearly different from the Java behaviour which is a shallow
copy.

I think this shows that it is mistaken to call the C++ member-wise
copy a "shallow copy".

Nov 27 '06 #10
* Old Wolf:
blangela wrote:
>A shallow copy is a member-wise copy. A deep copy is anything other
than a shallow copy. What could be simpler than that?

Firstly, if that is your definition then why not just call them
what they are: "member-wise copy" and "non member-wise copy" ?

Second, that's not the commonly accepted definition of
'shallow copy' and 'deep copy' in computer science, so
it is confusing. Look at this example, where Foo is some class:

// C++:
class S { public: Foo foo; };

// Java:
class S { public Foo foo; };

In Java, assigning an object of type S to another object of type S
results in both objects having a handle on a single shared instance
of Foo. I think we would agree that this is a shallow copy.
It is, but not of the object. It is a shallow copy of references.
Thinking of references as the referred to objects is a common conceptual
error among Java programmers.

In C++, the same assignment results in both objects having their
own Foo objects (so there are now two Foos in existence).

Now, you are trying to say that the C++ behaviour is a "shallow copy".
It is clearly different from the Java behaviour which is a shallow
copy.
You're comparing apples to politicians.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 27 '06 #11

Greg wrote:
blangela wrote:
I have decided (see earlier post) to paste my Word doc here so that it
will be simpler for people to provide feedback (by directly inserting
their comments in the post). I will post it in 3 parts to make it more
manageable.

Below is a draft of a document that I plan to give to my introductory
C++ class.

Please note that I have purposely left out any mention of safety issues
in the ctors which could be resolved thru some combination smart
pointers or exception handling. These topics will be introduced in the
follow up course.

If anyone would like the complete document in MS Word (after I have
incorporated improvements you folks suggest), send me an e-mail with
"Deep versus Shallow Copy" as a title. The appearance in the Word doc
is much better (this tool is rather limited when it comes to formatting
choices and it seems to get the indentation wrong when translating from
Word).

PART 1:

Subject: Explanation of Deep versus Shallow Copy
Author: Bob Langelaan
Date: Nov. 25th, 2006

Note: The reader should already have studied the following C++
concepts in order to be able to understand this document: pointers and
references; the "new" and "delete" operators; the member
initialization list (MIL); the "this" pointer.

1.0 Introduction

Let us start with the following class:

class Example1
{
private:
int ii;
double dd;
ABC abc;
};

I think the paper would be improved by using a more meaningful class
than "Example1" as the example. After all, if the example appears to be
contrived, then the student may question the relevancy of the material.
So the more "realistic" the example provided, the more likely that a
student will be able to apply it to C++ code they see and to the C++
code that they write. The specific class chosen does not matter all
that much: a "Shape" class, or a "Vehicle" class, or even a "String"
class are some of the usual choices.

Another important programming lesson is to choose the names of
identifiers carefully. Well-chosen names document the program and
minimize the likelihood of making a mistake. For that reason, this
program is not setting a good example by having identifiers with names
that differ only by one character at the very end of the name.
"Example1" and "Example2" (besides not communicating what either class
actually represents) may suggest that class names should resemble each
other as much as possible - when in fact the goal is the opposite.
Because the last thing that a programmer wants is to have two classes
whose names are easy to mix up.

Greg
I have to agree. Abstract examples just don't do it for me. I've
written on my web site about the importance of good examples.

Yes, they're really hard to come up with, but that's what your students
are paying you for.

A good example will make the students *want* to get it right and
further, make the issue stand out. With a duff example though they
normally can't care less.
K

Nov 27 '06 #12
blangela:
A shallow copy is a member-wise copy. A deep copy is anything other
than a shallow copy. What could be simpler than that?

There's also bit-wise copy:

memcpy(&obj1,&obj2,sizeof obj1);

This might differ from member-wise copy if:

(1) There's padding.
(2) Any members have an overloaded assignment operator.

--

Frederick Gotham
Nov 27 '06 #13

Frederick Gotham wrote:
blangela:
A shallow copy is a member-wise copy. A deep copy is anything other
than a shallow copy. What could be simpler than that?


There's also bit-wise copy:

memcpy(&obj1,&obj2,sizeof obj1);

This might differ from member-wise copy if:

(1) There's padding.
(2) Any members have an overloaded assignment operator.

--

Frederick Gotham
Good point!

Nov 27 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Tony Johansson | last post by:
Hello! I'm reading in a book about C++ and that is something that sound strange. It says "Pointers have reference-assignment semantics similar to those in Java. For example, after the...
2
by: Alex | last post by:
Entering the following in the Python shell yields >>> help(dict.copy) Help on method_descriptor: copy(...) D.copy() -> a shallow copy of D >>>
4
by: fperfect13 | last post by:
Hi, I wanted to perform a deep copy of an array. Searching on google I ran into different opinions : C# Interview Questions (http://blogs.wwwcoder.com/tsvmadhav/archive/2005/04/08/2882.aspx)...
2
by: bonk | last post by:
I have come across the need to distinguish between the creation of a deep and a shallow copy and with great interest I have read this article: ...
26
by: saxenavaibhav17 | last post by:
what is Deep Copy, Shallow copy and Bitwise copy, Memberwise copy? and what is the difference between them? pls help vaibhav
9
by: blangela | last post by:
2.0 Sample Code class ABC // dummy class used below {}; class Example2 { public: Example2(); // default ctor Example2( const Example2 &); // copy ctor
1
by: blangela | last post by:
3.0 Advanced Topic Addendum There are a few cases where the C++ compiler cannot provide an overloaded assignment operator for your class. If your class contains a const member or/and a...
4
by: shuisheng | last post by:
Dear All, Is there any easy way to make sure all my object copies are deep copy or shallow copy? I do not like to implement it in each class one by one. Thanks, Shuisheng
3
by: raylopez99 | last post by:
The "C# Cookbook" (O'Reilly / Jay Hilyard), section 3.26, is on deep cloning versus shallow cloning. The scanned pages of this book are found here: http://www.sendspace.com/file/mjyocg (Word...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.