Implement object tracking, for example, in Boost :: Serialization

I implement the "clone" function for graphing objects in C ++, and part of the problem is to make sure that if there are two pointers to the same object, it is not cloned twice. I did this by saving map<void*, void*> , which saves the original object as a key and the cloned version as a value. When cloning an object, I use the template function to check if the object is on the map - if so, I return it using static_cast<T*> , otherwise I clone it and save the original and clone on the map with implicit conversion to void* .

The problem with this scheme is that if an object is mentioned in two places by different types (for example, by interface against a specific type), casting to void* may not lead to the same value. This means that the object is cloned twice.

I looked on the Internet for existing solutions and realized that Boost.Serialization had to solve the same problem. But after trawling through its source, I could not find the part that actually tracks pointers to objects.

Can someone help by suggesting a design that works, or by pointing to the part of the Boost code that does this?

+4
source share
2 answers

Before saving, draw a pointer using dynamic_cast<void*> - this will give you a pointer to void for the most derived object; this void pointer will have the same address for the same objects.

See also this question .

+4
source

I do not believe that simplified serialization handles this in a super-smart way. Look at the base_object function - it seems you need to manually specify what the base class is. This shows how to get the same pointer. Also note that to serialize derived classes, only virtual classes will be saved correctly this way, not virtual like standard layout types, you must serialize the derived class. I have no idea if they handle a generic pointer in this case.

So, the main idea would be that if you have a virtual class, the base should have a "serial" kind function. If you use this base, you have a common pointer and you can still call a virtual sequential function.

You might be better off creating a global identify<T> template and specializing it for all the types that need it. It may be error prone, but in no case does the boost approach avoid errors.

I did a lot of work to extend serialization, but avoided pointer logic - it just got confused, so I just don't do this level of serialization (without pointers in my serialized data).

+1
source

Source: https://habr.com/ru/post/1392421/


All Articles