Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 共享\u ptr删除该对象_C++_Boost_Shared Ptr - Fatal编程技术网

C++ 共享\u ptr删除该对象

C++ 共享\u ptr删除该对象,c++,boost,shared-ptr,C++,Boost,Shared Ptr,在这里,对象从LocalMethod返回时被释放,因为classNamePtr超出范围。shared_ptr是否足够聪明,可以知道ClassName对象仍在作用域中,而不删除它 shared_ptr是否足够聪明,可以知道ClassName对象是 是否仍在范围内而不删除它 共享ptr不是这样工作的。当您在构造共享的\u ptr时传递一个指针时,共享的\u ptr将承担该指针对象的所有权,在本例中,*this。换句话说,由于共享的ptr现在拥有它,所以共享的ptr假定对指针对象的生命周期具有完全的控

在这里,对象从LocalMethod返回时被释放,因为classNamePtr超出范围。shared_ptr是否足够聪明,可以知道ClassName对象仍在作用域中,而不删除它

shared_ptr是否足够聪明,可以知道ClassName对象是 是否仍在范围内而不删除它

共享ptr不是这样工作的。当您在构造共享的\u ptr时传递一个指针时,共享的\u ptr将承担该指针对象的所有权,在本例中,*this。换句话说,由于共享的ptr现在拥有它,所以共享的ptr假定对指针对象的生命周期具有完全的控制权。因此,拥有指针对象的最后一个共享\u ptr将删除它

如果在ClassName::LocalMethod之外没有classNamePtr的副本,则可以传递一个在构造classNamePtr时不执行任何操作的删除程序。根据您的情况调整示例:

void ClassName::LocalMethod( )
{
    boost::shared_ptr<ClassName> classNamePtr( this );

    //some operation with classNamePtr
    return;
}
这是一个更合适的官方方法,它比null deleter方法要简单得多


也可能是您实际上不需要首先创建共享的ptr。关于classNamePtr的一些操作,这一节中有什么内容?可能还有比前两种更好的方法。

为对象创建共享的ptr意味着什么?这意味着共享ptr的持有者现在对该对象拥有所有权。所有权意味着该对象将在其需要时被删除。当共享\u ptr的持有者销毁其共享\u ptr时,假设该对象没有其他共享\u ptr,这将导致该对象可能被销毁

当共享\u ptr是类的成员时,这意味着共享\u ptr所指向的对象的生存期至少与共享\u ptr所属的对象的生存期一样长。当共享\u ptr位于堆栈上时,这意味着共享\u ptr所指向的对象的生存期至少与创建它的范围一样长。一旦对象从堆栈中脱落,它可能会被删除

只有在最初分配对象时,才应该使用指针并将其包装到共享_ptr中。为什么?因为对象不知道它是否在共享的\u ptr中。它不可能知道。这意味着创建原始共享\u ptr的人现在有责任将其传递给需要共享该内存所有权的其他人。共享所有权工作的唯一方式是通过shared_ptr的复制构造函数。例如:

class ClassName : public enable_shared_from_this<ClassName> 
{ 
public: 
    void LocalMethod()
    { 
        boost::shared_ptr<ClassName> classNamePtr = shared_from_this(); 
    } 
} 

// ...

// This must have been declared somewhere...
shared_ptr<ClassName> p(new ClassName);
// before you call this:
p->LocalMethod();
请注意,这里有一个成本。从\u启用\u共享\u这会在类中放置boost::weak\u ptr。但是没有虚拟的开销或类似的东西;它不会使类成为虚拟的。从\u启用\u共享\u这是一个模板,因此您必须这样声明它:

void ClassName::LocalMethod()
{
    boost::shared_ptr<ClassName> classNamePtr(shared_from_this());

    //some operation with classNamePtr
    return;
}

让我知道做这件事的正确方法——做什么?你到底想干什么?一种方法可能是不使用共享的\u ptr,直接使用这个或对象的成员,而不使用这个->。但你可能出于某种原因试图使用共享ptr——也许可以更直接地问一下。问题:你为什么要首先创建共享ptr?正确的方法很可能是重新设计。为什么您需要一个共享的ptr来分配一个非动态分配的对象?我不相信null deleter方法。如果他正在调用的那些函数期望声明对象的所有权,那么使用基于null deleter的函数将不允许它们这样做。他们可能会在稍后指向死掉的记忆。如果这些函数没有所有权,那么为什么它们要从共享的ptr开始?@Nicol Bolas:这就是为什么我说在ClassName::LocalMethod之外不会有classNamePtr的副本。如果我知道classNamePtr的一些操作,我可以给出更好的建议。话虽如此,我还是编辑了答案,指出启用的\u共享\u from\u更合适,OP应该重新考虑整体设计。启用的\u共享的\u from\u唯一需要记住的是,在调用共享的\u from\u this之前,您必须在某个点将对象放置在共享的\u ptr中。我通常通过创建一个静态工厂方法来实现这一点,该方法返回一个共享指针并使原始构造函数私有。
shared_ptr<int> p1 = new int(12);
shared_ptr<int> p2 = p1.get();
shared_ptr<int> p3 = p1;
void ClassName::LocalMethod()
{
    boost::shared_ptr<ClassName> classNamePtr(shared_from_this());

    //some operation with classNamePtr
    return;
}
class ClassName : public boost::enable_shared_from_this<ClassName>