为对象创建shared_ptr 是什么意思?这意味着shared_ptr 的持有者现在拥有该对象的所有权。所有权意味着对象将在他需要时被删除。当shared_ptr 的持有者销毁其shared_ptr 时,这将导致该对象可能被销毁,假设该对象没有其他shared_ptrs。
当shared_ptr 是类的成员时,这意味着shared_ptr 指向的对象的生命周期至少与shared_ptr 指向的对象一样长是其中的一员。当shared_ptr 在堆栈上时,这意味着shared_ptr 指向的对象的生命周期将至少与创建它的范围一样长。一旦对象从堆栈中掉下来,它可能被删除。
唯一您应该将指针包装到shared_ptr 中的时间是分配对象最初。为什么?因为一个对象不知道它是否在shared_ptr 中。它不能知道。这意味着创建原始shared_ptr 的人现在有责任将其传递给需要共享该内存所有权的其他人。共享所有权起作用的唯一方法是通过shared_ptr 的复制构造函数。例如:
shared_ptr<int> p1 = new int(12);
shared_ptr<int> p2 = p1.get();
shared_ptr<int> p3 = p1;
shared_ptr 的复制构造函数在p1 和p3 之间创建共享所有权。请注意,p2 不与p1 共享所有权。他们都认为他们拥有相同内存的所有权,但这与共享内存不同。因为他们都认为他们拥有它的独特所有权。
因此,当三个指针被销毁时,会发生以下情况。首先,p3 将被销毁。但是由于 p3 和 p1 共享该整数的所有权,因此该整数还不会被销毁。接下来,p2 将被销毁。因为它认为它是整数的唯一持有者,所以它会销毁它。
此时,p1 指向已删除的内存。当p1被销毁时,它认为它是整数的唯一持有者,所以它会销毁它。这不好,因为它已经被销毁了。
你的问题是这样的。你在一个类的实例中。你需要调用你的一些函数来获取shared_ptr。但是您所拥有的只是this,它是一个常规指针。你是做什么的?
您将获得一些建议 enable_shared_from_this 的示例。但是考虑一个更相关的问题:“为什么这些函数将shared_ptr 作为参数?”
函数采用的指针类型表示该函数对其参数的作用。如果一个函数采用shared_ptr,这意味着它需要拥有指针。它需要共享内存的所有权。因此,请查看您的代码并询问这些函数是否真的需要 获得内存的所有权。他们是将shared_ptr 长期存储在某个地方(即:在一个对象中),还是只是在函数调用期间使用它们?
如果是后者,那么函数应该采用裸指针,而不是shared_ptr。这样,他们不能声明所有权。然后你的界面是自我记录的:指针类型解释了所有权。
但是,您可能正在调用真正需要共享所有权的函数。然后你需要使用enable_shared_from_this。首先,您的类需要从enable_shared_from_this 派生。然后,在函数中:
void ClassName::LocalMethod()
{
boost::shared_ptr<ClassName> classNamePtr(shared_from_this());
//some operation with classNamePtr
return;
}
请注意,这里是有成本的。 enable_shared_from_this 在课堂上放了一个 boost::weak_ptr。但是没有虚拟开销之类的;它不会使类成为虚拟的。 enable_shared_from_this 是一个模板,所以你必须像这样声明它:
class ClassName : public boost::enable_shared_from_this<ClassName>