justin
justin

Reputation: 53

Copy base class reference value to map with shared_ptr

I have a base class and derived class (BaseObj and Derived Obj) and I need to have a map of string keys that would have pointers to the objects:

std::map<std::string, std::shared_ptr<BaseObj>

Here is the complication: the map values need to be on the heap as the objects will go out of scope, however the objects are passed by reference to the function:

void insert_in_map(std::string, const& BaseObj);

Since the reference is to the base class, there is no way (to my knowledge) of copying the underlying value to the heap and getting a base pointer to it. The only solution I can think of is to change the function prototype to accept a shared_ptr that has already allocated the object on the heap. However, I really would like to avoid creating the shared_ptr in all the callers, especially since the shared_ptr has to be copied into the map.

Any ideas?

Upvotes: 0

Views: 1283

Answers (1)

Slava
Slava

Reputation: 44238

Any ideas?

Yes, you should change your function signature to:

void insert_in_map(std::string, std::unique_ptr<BaseObj>);

so this will clearly show that function takes ownership of the object. Your map probably also should be changed to have std::unique_ptr instead of shared one, unless you really need shared ownership. In that case you can change them both to std::shared_ptr (which could be little bit more effective than converting std::unique_ptr to std::shared_ptr inside function). I would create type alias and use it in the both cases.

However, I really would like to avoid creating the shared_ptr in all the callers, especially since the shared_ptr has to be copied into the map.

It does not have to be copied, it can be moved into the map, so your reasoning is strange - you should not take ownership of an object, passed by const reference.

If you cannot change function signature, you could add virtual method std::shared_ptr<BaseObject> clone() into base class and override accordingly. But that seems to be unreasonable in your case, since you can change function signature, you do not want by some strange reasons.

Upvotes: 2

Related Questions