Reputation: 53
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
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