-->

显式删除一个shared_ptr(Explicitly deleting a shared_ptr)

2019-07-31 10:46发布

这里简单的问题:你是不允许直接删除一个boost::shared_ptr自己吗? 你应该永远不会消失?

澄清,我不是指删除由持有指针shared_ptr 。 我的意思实际shared_ptr本身。 我知道大多数人建议不这样做,所以我只是想知道,如果它是确定明确的做到这一点。

Answer 1:

你的问题是不明确的。 如果你分配一个shared_ptr动态那么你肯定是不允许delete它,只要你想要的。

但是,如果你询问你是否要允许删除任何对象正在由管理shared_ptr ,那么答案是...它依赖。 如果shared_ptr::unique返回true,然后调用shared_ptr::reset会删除被管理对象。 但是,如果shared_ptr::unique返回false,这意味着有超过一个shared_ptr该对象的分享所有权。 在这种情况下调用reset只会造成引用计数1被递减,对象的实际删除将于当最后shared_ptr该对象无论是管理超出范围或者其本身就是reset

编辑:
您的编辑后,看来你是问有关删除一个动态分配shared_ptr 。 事情是这样的:

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

// do something with sp

delete sp;

这是允许的,并会按预期工作,虽然这将是一个不寻常的使用情况。 唯一需要注意的是,如果在分配和删除之间sp创建另一个shared_ptr共享对象的所有权,删除sp会不会导致对象,当对象的引用计数为0时才会发生的缺失。



Answer 2:

[编辑:您可以delete一个shared_ptr当且仅当它与创建new ,与任何其他类型。 我想不出为什么你会创建一个shared_ptrnew ,但没有什么能阻止你。]

嗯,你可以delete ptr.get();

这样做会导致几乎不可避免地不确定的行为既可以当其他共享业主使用他们shared_ptr访问现已删除的对象,或最后shared_ptr对象被破坏,并且对象被再次删除。

所以,不,你不应该。

的目的shared_ptr是管理,没有一个“人”有删除的权利或责任的对象,因为可能有其他人共享所有权。 所以,你应该没有想,无论是。



Answer 3:

你不能强迫它的引用计数为零,没有。

想想,将需要为工作。 你需要去的shared_ptr每次使用的地方,清除它。

如果没有强制共享指针删除,并将其设置为NULL,这将是就像一个weak_ptr的。 然而,使用shared_ptr的代码中的所有这些地方都没有准备好,并期望成为持有有效的指针。 他们没有理由去检查NULL,所以这些代码位将崩溃。



Answer 4:

如果要模拟计数减量,你可以做手工,在像这样的堆:

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;
}

或使用堆栈上std::shared_ptr::reset() ,如下所示:

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;
} 

但它是没有多大用处的。



Answer 5:

Expliticly删除就派上用场了一些(很?)罕见的情况下。

除了明确删除,有时你必须明确地破坏一个共享指针,当你是“删除”吧!

与C代码接口时,路过一个shared_ptr作为一个不透明的价值的东西可以得到奇怪的。

例如我已经在对经过的物体,并从其中被写入C. Lua脚本语言以下(www.lua.org)

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 );
}

因此多数民众赞成在一些malloc分配内存一个shared_ptr。 相反的是这样的...(设置将刚打电话之前Lua的垃圾收集的对象,“自由就是这样)。

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;
}


文章来源: Explicitly deleting a shared_ptr