jackel7777 wrote: |
---|
when we usually do a copy constructor we pass in the value as reference and do a copy of all its members, instead we could do this way by just : |
No, you are misunderstanding.
cloning deep copies a pointer, it doesn't replace a copy constructor. Furthermore you cannot assign
this
, so your example is incorrect.
Cloning is useful for objects that own a pointer to an abstract type. Like in your original example:
- Person owns a Vehicle*
- Vehicle is an abstract type
Therefore:
- Vehicle would need a clone() function
- Person would clone the vehicle in its copy ctor
The vehicle would not clone itself, nor would the person clone itself.
jackel7777 wrote: |
---|
This code shows that clone does not do a deep copy cause if i delete obj2, the entire heap is deleted and obj1 does a double free? |
Cloning performs a deep copy of whatever you're cloning as long as the object properly copies itself. As ne555 mentioned, arr does not have a custom copy ctor to deep copy the 'p' member, therefore you have this problem.
Here, you are misusing the clone pattern. 'arr' is not abstract so there's no point to it. You might as well just call the copy ctor directly.
Let me put it this way. Cloning lets you deep copy a pointer when that point is abstract. Continuing with the original example of Vehicle/Car/Bike/Truck:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
Vehicle* a = whatever;
// we want to deep copy 'a' to another pointer
// without cloning, we'd have to do something like this:
Vehicle* b;
if( a_is_a_Car )
b = new Car( *static_cast<Car*>(a) );
if( a_is_a_Bike )
b = new Bike( *static_cast<Bike*>(a) );
if( a_is_a_Truck )
b = new Truck( *static_cast<Truck*>(a) );
// .. etc (repeat for all possible types of vehicles
|
Obviously this is a bad idea. Therefore we can just use the clone pattern:
1 2 3 4
|
Vehicle* a = whatever;
Vehicle* b = a->clone(); // doesn't matter what kind of Vehicle 'a' is
// by cloning it, 'b' will be the same kind of vehicle
|
Note that Vehicle will still need to deep copy all of its members in its copy constructor. Cloning doesn't replace the need to implement copy constructors, it just let's you dynamically copy something without knowing its exact type.