|
|
|
|
|
|
|
As we have discussed, the built-in assignment operator ( =) leads to a shallow copy when class objects point to dynamic data. The issue of deep versus shallow copying can also appear in another context: initialization of one class object by another. C++ defines initialization to mean |
|
|
|
|
|
|
|
|
1. initialization in a variable declaration |
|
|
|
 |
|
|
|
|
Date datel = date2; |
|
|
|
|
|
|
|
|
2. passing a copy of an actual parameter to a formal parameter (that is, pass-by-value) |
|
|
|
|
|
|
|
|
3. returning an object as the value of a function |
|
|
|
 |
|
|
|
|
return someObject; |
|
|
|
|
|
|
|
|
By default, C++ performs such initializations using shallow copy semantics. In other words, the newly created class object is initialized via a member-by-member copy of the old object without regard for any data to which the class members may point. For our Date class, the result would again be two class objects pointing to the same dynamic data. |
|
|
|
|
|
|
|
|
To handle this situation, C++ has a special kind of constructor known as a copy-constructor. In a class declaration, its prototype has the following form: |
|
|
|
|
|
|
|
|
class SomeClass
{
public:
.
.
.
SomeClass( const SomeClass& someObject ); // Copy-constructor
.
.
.
}; |
|
|
|
|
|
|
|
|
Notice that the function prototype does not use any special words to suggest that this is a copy-constructor. You simply have to recognize the pattern of symbols: the class name followed by a parameter list, which contains a single parameter of type |
|
|
|
|
|