How do we return a unique_pointer member from a member function?

余生颓废 提交于 2019-12-03 13:33:06

Your Derived1 case cannot be handled the way you want by unique_ptr. You want multiple smart pointers to the same resource. unique_ptr is simply not an option for that. There's no way around that.

You could stick with a unique_ptr member, but make your function return a raw pointer.

virtual int *get() = 0;

This is troublesome for your Derived2 class, because it is not clear whether the caller should free the pointed-to memory. I recommend you do not do this.

You could use a shared_ptr member, as you suggested, and make your function return that. This is fully functional in your Derived2 class, but as you point out, sub-optimal.

It is still the cleanest solution, though. For callers that only know they've got a Base, you need some way of informing them (either manually or through the returned type) what they should do when they're done with get()'s result, so you cannot return unique_ptr<int> anyway.

The only way a function returning unique_ptr<int> could be useful is if the caller already knows you've got a Derived2. But then, you can just add a new member:

virtual shared_ptr<int> get() {
  return get_unique();
}
virtual unique_ptr<int> get_unique() {
    std::unique_ptr<int> pInt(new int());
    return pInt;
}

I would only do that if profiling shows that the shared_ptr<int> get() member actually adds measurable overhead, though. There's a good chance that your shared_ptr<int> implementation is sufficient, performance-wise, and then readibility should probably be a reason for not adding a new member.

The purpose of unique_ptr is to point to a resource from a unique place. If you need to point to this resource from multiple places, unique_ptr is no longer appropriate. You should use shared_ptr in that case.
If releasing ownership of the resource is appropriate for your logic, then just use:

unique_ptr<int> get()
{
   return move(pInt);// this will move the ownership of the resource away from the member field
}

... but from now on, the pInt is no longer valid.

If you are careful with resources (if you are not worried of dangling pointers), than just return raw pointer to the resource (but please don't prefer this to use of shared_ptr).

In case of using shared_ptr, be careful of cyclic dependency, use weak_ptr do counter it. Here is something about it: http://geekwentfreak-raviteja.rhcloud.com/blog/2014/07/06/c11-how-to-create-cyclic-dependencies-with-shared_ptr-and-how-to-avoid-them/?_sm_au_=irVM6PVF1TR4nGMW

Post edit: When you use unique_ptr as a member field, you are loosing copy constructor, because unique_ptr cannot be copied. FYI

But still, use of unique_ptr seems to me as extra overhead already, in which just use shared_ptr or int directly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!