Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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_Boost Smart Ptr - Fatal编程技术网

C++ 显式删除共享\u ptr

C++ 显式删除共享\u ptr,c++,boost,shared-ptr,boost-smart-ptr,C++,Boost,Shared Ptr,Boost Smart Ptr,这里有一个简单的问题:是否允许您自己明确删除boost::shared\u ptr?你应该这样做吗 澄清一下,我的意思不是删除共享\u ptr所持有的指针。我指的是实际的共享\u ptr本身。我知道大多数人建议不要这样做,所以我只是想知道显式地这样做是否可以。您不能强制其引用计数为零,否 想一想这需要什么才能起作用。您需要前往使用共享ptr的每个地方并清除它 如果您确实强制共享指针删除并将其设置为NULL,那么它就像一个弱的ptr。但是,代码中使用该共享\u ptr的所有位置都没有准备好,并且希

这里有一个简单的问题:是否允许您自己明确删除
boost::shared\u ptr
?你应该这样做吗


澄清一下,我的意思不是删除
共享\u ptr
所持有的指针。我指的是实际的
共享\u ptr
本身。我知道大多数人建议不要这样做,所以我只是想知道显式地这样做是否可以。

您不能强制其引用计数为零,否

想一想这需要什么才能起作用。您需要前往使用共享ptr的每个地方并清除它


如果您确实强制共享指针删除并将其设置为NULL,那么它就像一个弱的ptr。但是,代码中使用该共享\u ptr的所有位置都没有准备好,并且希望保存一个有效指针。他们没有理由检查NULL,因此这些代码位将崩溃。

你的问题不清楚。如果您已经动态分配了
共享\u ptr
,那么您当然可以
随时删除它

但是,如果您询问是否允许删除由
共享\u ptr
管理的任何对象,那么答案是。。。视情况而定。如果
shared_ptr::unique
返回true,则调用
shared_ptr::reset
将删除托管对象。但是,如果
shared_ptr::unique
返回false,则表示有多个
shared_ptr
s共享该对象的所有权。在这种情况下,调用
reset
只会导致引用计数减少1,当管理该对象的最后一个
共享\u ptr
超出范围或自身
reset
时,将实际删除该对象

编辑:
编辑后,您似乎在询问删除动态分配的
共享\u ptr
。大概是这样的:

auto sp = new boost::shared_ptr<int>( new int(42) );

// do something with sp

delete sp;
auto-sp=newboost::shared_ptr(newint(42));
//用sp做点什么
删除sp;

这是允许的,并将按预期工作,尽管这将是一个不寻常的用例。唯一需要注意的是,如果在
sp
的分配和删除之间,您创建了另一个共享对象所有权的
shared\u ptr
,则删除
sp
不会导致删除对象,这只会在对象的引用计数变为0时发生。

[编辑:你可以
删除
共享的
当且仅当它是用
新建的
创建的,与任何其他类型相同。我不明白你为什么要用
新建的
创建
共享的
,但没有什么能阻止你。]

那么,您可以编写
删除ptr.get();

这样做几乎不可避免地会导致未定义的行为,无论是当其他共享所有者使用其
共享ptr
访问现在已删除的对象时,还是当对象的最后一个
共享ptr
被销毁时,该对象再次被删除

所以不,你不应该


shared\u ptr
的目的是管理一个任何“个人”都无权或没有责任删除的对象,因为可能会有其他人共享所有权。因此,您也不应该希望这样做。

如果您想模拟计数递减,可以在堆上手动执行,如下所示:

int main(void) {
    std::shared_ptr<std::string>* sp = new std::shared_ptr<std::string>(std::make_shared<std::string>(std::string("test")));
    std::shared_ptr<std::string>* sp2 = new std::shared_ptr<std::string>(*sp);
    delete sp;

    std::cout << *(*sp2) << std::endl;    // test
    return 0;
}

但它并没有那么有用。

在一些(非常?)罕见的情况下,明确删除很有用

除了显式删除之外,有时在“删除”共享指针时还必须显式销毁它

当与C代码交互时,事情会变得很奇怪,将共享的_ptr作为不透明值传递

例如,我有以下内容,用于向用C编写的Lua脚本语言传递对象和从中传递对象(www.Lua.org)

静态无效推送(lua_State*L,std::shared_ptr sp)
{
if(sp==nullptr){
卢阿努普什尼勒(L);
返回;
}
//这基本上是从C++的角度来看的。
void*ud=lua_newuserdata(L,sizeof(std::shared_ptr));
//复制构造函数,碰撞参考计数。
新(ud)标准::共享ptr(sp);
luaL_setmetatable(L,B::class_name);
}
因此,这是某个malloc'd内存中的共享\u ptr。相反的是…(在Lua垃圾收集对象并“释放”它之前调用设置)

static int destroy(lua_State*L)
{
//抓取不透明指针
void*ud=luaL\u checkudata(L,1,B::class\u name);
std::shared_ptr*sp=静态_cast(ud);
//显式调用,因为这是“新位置”
//递减ref计数
sp->~shared_ptr();
返回0;
}

当然可以删除(动态分配)共享\u ptr;删除它的内容是一个完全不同的问题;-)我认为你在寻找
弱\u ptr
。动态分配
共享\u ptr
违背了使用
共享\u ptr
的目的。你到底为什么要在堆上分配
共享\u ptr
?你的问题与“如果我用new分配一个对象,我可以显式地删除它吗?”……答案当然是肯定的——你可以而且应该这样做。对象的类型无关紧要。
int main(void) {
    std::shared_ptr<std::string> p = std::make_shared<std::string>(std::string("test"));
    std::shared_ptr<std::string> p2 = p;
    p.reset();

    std::cout << *p2 << std::endl;    // test
    return 0;
} 
static void push( lua_State *L, std::shared_ptr<T> sp )
{
    if( sp == nullptr ) {
        lua_pushnil( L );
        return;
    }

    // This is basically malloc from C++ point of view.
    void *ud = lua_newuserdata( L, sizeof(std::shared_ptr<T>));

    // Copy constructor, bumps ref count.
    new(ud) std::shared_ptr<T>( sp );

    luaL_setmetatable( L, B::class_name );
}
static int destroy( lua_State *L )
{
    // Grab opaque pointer
    void* ud = luaL_checkudata( L, 1, B::class_name );

    std::shared_ptr<T> *sp = static_cast<std::shared_ptr<T>*>(ud);

    // Explicitly called, as this was 'placement new'd
    // Decrements the ref count
    sp->~shared_ptr();

    return 0;
}