我在阅读Boost.Asio示例时遇到了enable_shared_from_this
,在阅读了文档之后,我仍然不知道应该如何正确使用它。谁能给我举个例子,解释一下什么时候使用这个类是有意义的。
发布于 2009-04-03 02:00:52
它使您能够将一个有效的shared_ptr
实例转换为this
,而您所拥有的只有this
。如果没有它,您将无法获得this
的shared_ptr
,除非您已经拥有一个成员身份。boost documentation for enable_shared_from_this中的此示例
class Y: public enable_shared_from_this<Y>
{
public:
shared_ptr<Y> f()
{
return shared_from_this();
}
}
int main()
{
shared_ptr<Y> p(new Y);
shared_ptr<Y> q = p->f();
assert(p == q);
assert(!(p < q || q < p)); // p and q must share ownership
}
即使方法f()
没有成员实例,它也会返回一个有效的shared_ptr
。请注意,您不能简单地这样做:
class Y: public enable_shared_from_this<Y>
{
public:
shared_ptr<Y> f()
{
return shared_ptr<Y>(this);
}
}
这个返回的共享指针将有一个与“正确的”不同的引用计数,当对象被删除时,其中一个将丢失并持有一个悬空的引用。
enable_shared_from_this
已成为C++ 11标准的一部分。你也可以从那里获得它,也可以从boost获得。
发布于 2011-04-05 15:00:07
从Dobbs博士关于弱指针的文章中,我认为这个例子更容易理解(来源:http://drdobbs.com/cpp/184402026):
像这样的...code将无法正常工作:
int *ip = new int;
shared_ptr<int> sp1(ip);
shared_ptr<int> sp2(ip);
这两个shared_ptr
对象都不知道对方,所以当它们被销毁时,它们都会尝试释放资源。这通常会导致问题。
类似地,如果一个成员函数需要一个拥有被调用对象的shared_ptr
对象,它不能只动态创建一个对象:
struct S
{
shared_ptr<S> dangerous()
{
return shared_ptr<S>(this); // don't do this!
}
};
int main()
{
shared_ptr<S> sp1(new S);
shared_ptr<S> sp2 = sp1->dangerous();
return 0;
}
这段代码与前面的示例具有相同的问题,尽管形式更为微妙。在构造时,shared_pt
r object sp1
拥有新分配的资源。成员函数S::dangerous
中的代码不知道该shared_ptr
对象,因此它返回的shared_ptr
对象与sp1
不同。将新的shared_ptr
对象复制到sp2
没有任何帮助;当sp2
超出作用域时,它将释放资源,而当sp1
超出作用域时,它将再次释放资源。
避免这个问题的方法是使用类模板enable_shared_from_this
。该模板接受一个模板类型参数,该参数是定义托管资源的类的名称。反过来,该类必须从模板中公开派生;如下所示:
struct S : enable_shared_from_this<S>
{
shared_ptr<S> not_dangerous()
{
return shared_from_this();
}
};
int main()
{
shared_ptr<S> sp1(new S);
shared_ptr<S> sp2 = sp1->not_dangerous();
return 0;
}
执行此操作时,请记住调用shared_from_this
的对象必须属于shared_ptr
对象。这是行不通的:
int main()
{
S *p = new S;
shared_ptr<S> sp2 = p->not_dangerous(); // don't do this
}
发布于 2012-06-13 21:25:41
请注意,使用boost::intrusive_ptr不会遇到此问题。这通常是解决这个问题的一种更方便的方法。
https://stackoverflow.com/questions/712279
复制相似问题