C++ – How to Copy and Alter Object with unique_ptr

cc++14object-orientedsmart-pointer

I basically have the following situation:

                         +------------------+
                         |                  |
                         |   Input object   |
                         |                  |
                      +--+------------------+--+
unique_ptr<Subobject 1>                        |unique_ptr<base class of Subobject 2>
                      |                        |
                      |                        |
                      |                        |
                      |                        |
             +--------v--------+     +---------v-------+
             |                 |     |                 |
             |   Subobject 1   |     |   Subobject 2   |
             |                 |     |                 |
             +-----------------+     +-----------------+

I have a class that takes this input object, does some calculation, and outputs a new output object, that points in some places back to the original input object this I need separate input objects for every calculation.
Now I would like to be able to queue multiple calculations with very similar input objects i.e. with Subobject 1 or 2 changed for a different object in order for a human to be able to compare results and find the best solution. As the objects are created based on XML input data, whenever I found a list of Subobjects instead of just one I wanted to just copy the top level object and swap only the values that needed to be swapped, but then I realized that unique_ptr prevents copying.
I may have designed myself into a corner here, but is there any way to facilitate this method or am I stuck rebuilding the entire object manually for every permutation?

Best Answer

Implement the copy constructor of your top level object ("Input object") to do a deep copy of the two subobjects. In the case of Subobject 2, since it uses a pointer to base, you may need to implement a virtual clone() method on the subobject so that the right derived type gets created & copied.

It's not less work then manually rebuilding the entire object every permutation, but might be more pleasant to work with.

However if you need to to share instance data, then you would need to switch to std::shared_ptr.

In either case, consider moving the std::unique_ptr or the std::shared_ptr inside the subobject class, and making the subobjects into "handle" classes which hold a pointer to the resource and take care of the appropriate copy semantics. Then the outer object doesn't need to know the details of sharing or copying. Note that if you do this then your class hierarchy for subobject 2 would have to be a hierarchy of different types of resource classes, since if the handle object is held by value it can no longer be polymorphic itself but would have to hold a polymorphic resource.

Related Topic