Lopper
Lopper

Reputation: 3537

C++: How to Perform Deep Cloning of Generic Type

To keep the long story short, I am unable to use the container from the STL and boost library and have to create my own.

My own generic container is coded in VC++6 and I need to know how to manually allocate memory for generic types before storing it in my own container. The generic types are all struct that can contain nested struct. All struct be it nested or not will contain only primitive types like char*, int, bool etc.

For example, when you call the insert function of std::vector, internally, std::vector will automatically perform a deep cloning of the generic type before storing it.

How can I duplicate this functionality (deep cloning of generic type) in my own container?

Please provide some sample code for performing deep cloning of generic type.

Upvotes: 4

Views: 2812

Answers (3)

xtofl
xtofl

Reputation: 41519

First and for all: if you want to clone any object, all it's aggregates should be cloned, too. This means that every struct/class involved in the cloning action should implement cloning behavior.

Then: the stl uses so called value-semantics: containers will always contain their elements 'by value'. Copying means creating copies of all container elements.

So in order to achieve cloning/deep copy behavior, the copy constructors of every member of the container's element type should implement deep copy behavior. Members of pointer-to-object type should also be deep-copied (not just copying the member pointer).

Note: code is untested, probably contains tons of exception-unsafety etc... and is merely used as a shallow :) example.

struct WithPointer {
   int* pint; 
   WithPointer( int value = 0 ) : pint( new int ) { *pint = value; }
   WithPointer( const WithPointer& other ) {
     pint = new int;
     *pint = *other.pint;
   }
   ~WithPointer( ) { delete pint; } // important!
}

This class can be 'deep-copied' using an stl container:

std::vector<WithPointer> v;
WithPointer wp(1);
v.push_back( wp );

std::vector<WithPointer> v2 = v;

Upvotes: 3

AnT stands with Russia
AnT stands with Russia

Reputation: 320719

std::vector does not perform any "deep cloning" by itself. When you insert something into std::vector, the vector allocates raw memory for the new element in the appropriate space and then creates a new element in that memory area by using direct initialization (normally through placement-new) from the element you passed to the insertion method. In other words, in order to make a copy for a class type, std::vector calls the copy-constructor of the class type. If the element type is not a class type or a class type without appropriately defined copy-constructor, the deep copy will not take place.

This is what you should do in your container type, if you want to simulate copying functionality of std::vector.

Upvotes: 3

Thanatos
Thanatos

Reputation: 44334

The std::vector (and most std containers) just call the type's copy constructor. This may or may not "deep clone" the object, depending on what the copy constructor does.

Upvotes: 5

Related Questions