提升shared_from_this和析构函数
我发现不允许在类的析构函数中调用shared_from_this:
https:// svn.boost.org/trac/boost/ticket/147
此行为是设计使然。由于析构函数会销毁该对象,因此为它创建一个shared_ptr是不安全的,因为一旦析构函数结束,它就会变得悬空。
我理解这个论点,但是如果我需要一个“shared_from_this”指针来清理引用(而不是共享所有权)怎么办?
这是一个我没有使用shared_ptr的例子:
class A{
public:
A( Manager * m ) : m_(m) {
m_->add(this);
}
~A() {
m_->remove(this);
}
private:
Manager * m_;
};
这里我尝试将它转换为共享指针。但我找不到完成析构函数的好方法:
class A : public boost::enable_shared_from_this< A > {
public:
typedef boost::shared_ptr< A > Ptr;
static Ptr create( Manager * m ) {
Ptr p( new A(m));
p->init();
return p;
}
~A() {
// NON-WORKING
// m_->remove( shared_from_this() );
}
private:
A( Manager * m ) : m_(m) { }
void init() {
m_->add(shared_from_this());
}
Manager * m_;
};
如何实现上面示例中的析构函数?
I found that it is not allowed to call shared_from_this in the destructor from a class:
https://svn.boost.org/trac/boost/ticket/147
This behavior is by design. Since the destructor will destroy the object, it is not safe to create a shared_ptr to it as it will become dangling once the destructor ends.
I understand the argument, but what if I need a "shared_from_this" pointer for cleaning up references ( not for sharing owner ship).
Here is an example where I'm not using shared_ptr:
class A{
public:
A( Manager * m ) : m_(m) {
m_->add(this);
}
~A() {
m_->remove(this);
}
private:
Manager * m_;
};
Here I have tried to translate it into shared pointers. But I can not find a good way to finish the destructor:
class A : public boost::enable_shared_from_this< A > {
public:
typedef boost::shared_ptr< A > Ptr;
static Ptr create( Manager * m ) {
Ptr p( new A(m));
p->init();
return p;
}
~A() {
// NON-WORKING
// m_->remove( shared_from_this() );
}
private:
A( Manager * m ) : m_(m) { }
void init() {
m_->add(shared_from_this());
}
Manager * m_;
};
How can I implement the destructor in the example above?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您的 Manager 对您的对象有一个
shared_ptr
,那么它就拥有它。因此,您的对象不应被破坏,因为管理器仍然拥有对它的引用。
您可以将弱指针传递给管理器,但管理器的工作是检查该指针是否仍然有效,如果无效则将其删除。
你的问题很有趣,但你的情况是由误解引起的。只要一个对象拥有对您的对象的引用,shared_ptr 的目标就是它不会被破坏。对于要调用的析构函数,您应该手动调用指针上的delete,这在使用shared_ptr 时是一个不好的行为。
简单定义谁真正拥有该对象,并给他们shared_ptr。如果代码的一部分偶尔需要您的对象(如果存在),则给它一个weak_ptr。
If your Manager has a
shared_ptr
to your object, then it owns it.Thus your object shall not be destructed, as the Manager still have a reference to it.
You may pass a weak pointer to the Manager, but then it's the work of the manager to check that the pointer is still valid, and delete it if not.
Your question is interesting, but your case is caused by a misconception. As long as an object own a reference to your object, it's the aim of shared_ptr that it will not be destructed. For the destructor to be called, you should have manually called delete on the pointer, which is a bad behavior when working with shared_ptr.
Simple define who really own the object, and give them the shared_ptr. If a part of code occasionally need your object - if it exists - then give it a weak_ptr.
如果 Manager 实例有一个指向您的类的共享指针,那么您的类将永远不会被销毁,直到该共享指针消失为止。因此,我假设 Manager 实际上将weak_ptr 存储到您的实例中,在这种情况下,Manager 的 API 可能应该接受您应该能够在析构函数中获取的weak_ptr。如果不能,只需在构造函数中创建一个并存储以供以后使用。
If the Manager instance has a shared_ptr to your class, your class will never be destroyed until that shared_ptr is gone. I assume, therefore, that Manager is actually storing a weak_ptr to your instance, in which case Manager's API should probably accept a weak_ptr which you should be able to get in the destructor. If you can't, just make one in your constructor and store it for later.
不。
您的第一个类很好(除了它是隐式声明的复制构造函数和复制赋值 - 与原始指针的使用无关)。
为什么要费心智能指针呢?因为它很时尚?
weak_ptr
经常被误解为类似指针的类(事实并非如此,它是一个弱引用的东西)。weak_ptr
很少适用。 (即使使用 Boost 文档,也会对何时适用weak_ptr
产生混淆。)enable_shared_from_this
更容易被误解。Don't.
Your first class is fine (except that it is an implicitly declared copy constructor and copy assignment - unrelated with the use of raw pointers).
Why bother with smart pointers? because it's fashionable?
weak_ptr
is often misunderstood as a pointer-like class (it is not, it is a weak reference thing).weak_ptr
is rarely appropriate. (Even with Boost documentation spreads confusion about whenweak_ptr
is appropriate.)enable_shared_from_this
is even easier to misunderstand.