I'm implementing a "clone" function for a graph of objects in C++ and part of the problem is to ensure that if there are two pointers to the same object, it is not cloned twice. I've done this by keeping a map<void*, void*>
that keeps the original object as the key and the cloned version as the value. When cloning an object, I use a template function to check if the object is in the map - if so, I return it with a static_cast<T*>
, otherwise, I clone it and store the original and clone in the map with an implicit conversion to void*
.
The problem with this scheme is that if an object is referred to in two places by different types (eg. by the interface vs the concrete type) the cast to void*
might not result in the same value. This would mean that object is cloned twice.
I looked on the web for existing solutions to this and realized that Boost.Serialization has to deal with the same problem. But after trawling through its source, I couldn't find the part that actually tracks pointers to objects.
Can anyone help by suggesting a design that works, or by pointing out the part of the Boost code that does this?
Before storing, cast the pointer with a dynamic_cast<void*>
- this will give you a void pointer to the most derived object; this void pointer will, for the same objects, have the same address stored.
See also this question.