Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

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.

like image 343
Lopper Avatar asked Dec 23 '22 07:12

Lopper


2 Answers

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.

like image 101
Thanatos Avatar answered Dec 24 '22 20:12

Thanatos


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;
like image 26
xtofl Avatar answered Dec 24 '22 21:12

xtofl