Shallow Copying
Because C++ does not know much about your class, the default copy
constructor and default assignment operators it provides use a copying
method known as a shallow copy (also known as a memberwise copy). A
shallow copy
means that C++ copies each member of the class individually using the
assignment operator. When classes are simple (eg. do not contain any
dynamically allocated memory), this works very well.
For example, let’s take a look at our Cents class:
1
2
3
4
5
6
7
8
9
10
|
class Cents
{
private :
int m_nCents;
public :
Cents( int nCents=0)
{
m_nCents = nCents;
}
};
|
When C++ does a shallow copy of this class, it will copy m_nCents
using the standard integer assignment operator. Since this is exactly
what we’d be doing anyway if we wrote our own copy constructor or
overloaded assignment operator, there’s really no reason to write our
own version of these functions!
However, when designing classes that handle dynamically allocated
memory, memberwise (shallow) copying can get us in a lot of trouble!
This is because the standard pointer assignment operator just copies the
address of the pointer — it does not allocate any memory or copy the
contents being pointed to!
Deep Copying
A
deep copy duplicates the object or variable being
pointed to so that the destination (the object being assigned to)
receives it’s own local copy. This way, the destination can do whatever
it wants to it’s local copy and the object that was copied from will
not be affected. Doing deep copies requires that we write our own copy
constructors and overloaded assignment operators.
Let’s go ahead and show how this is done for our MyString class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
MyString::MyString( const MyString& cSource)
{
m_nLength = cSource.m_nLength;
if (cSource.m_pchString)
{
m_pchString = new char [m_nLength];
strncpy (m_pchString, cSource.m_pchString, m_nLength);
}
else
m_pchString = 0;
}
|
As you can see, this is quite a bit more involved than a simple
shallow copy! First, we have to check to make sure cSource even has a
string (line 8). If it does, then we allocate enough memory to hold a
copy of that string (line 11). Finally, we have to manually copy the
string using strncpy() (line 14).