문제

I'd like to wrap raw pointer member to some smart pointer to prevent deleting inside a developing class. Owner of the object under pointer is outside of class. So, looks like boost::shared_ptr and std::auto_ptr does not fit. The following is a reduced example:

class Foo {
  boost::weak_ptr<Bar> m_bar;
public:
  void setBar(const Bar *bar) { // bar created on heap
    m_bar = bar;                // naturally compilation error
  }
};

Of course, it induces compilation error. What is a correct way to initialize weak_ptr from a raw pointer (if exist)?

도움이 되었습니까?

해결책

You can't do that, you can only create a weak_ptr out of a shared_ptr or another weak_ptr. So the idea would be that the owner of the pointer hold a shared_ptr instead of a raw pointer, and everything should be ok.

다른 팁

The only way to do it is by getting hold of a shared_ptr or weak_ptr that owns the pointer, otherwise the weak_ptr has no way to find the existing owner in order to share ownership with it.

The only way to get a shared_ptr from a raw pointer that is already owned by another shared_ptr is if Bar derives from enable_shared_from_this<Bar>, then you can do

m_bar = bar->shared_from_this();

The purpose of a weak pointer is to be unable to use the raw pointer if it had been deleted. However, if you have a raw pointer, the weak pointer has no way to know that it was deleted. Instead, you must have a shared_ptr somewhere which "owns" the raw pointer. Then you can create a weak_ptr which references the shared_ptr.

When the shared_ptr goes out of scope and is the last "strong" smart pointer, it will automatically delete the raw pointer. Then, when you try to lock the weak_ptr, it will see that there is no "strong" pointer remaining and therefore the object does not exist.

Everything you've said seems perfectly reasonable, except for one thing:

void setBar(const Bar *bar)

This shouldn't take a raw pointer. It should take a weak_ptr ideally, or possibly a shared_ptr if you have some compelling argument.

The actual owner of the object in question should construct the weak_ptr and than call setBar with that. This preserves the ownership semantics. It looks like what you're doing is having the owning object take a raw pointer and pass that to setBar. This creates a semantic gap in the ownership of the object.

Pass shared pointer instead of raw pointer, and create your weak pointer from that shared pointer. This is really the only way if owner of the pointer is outside of a class.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top