如何测试shared_ptr是空还是什么都没有

Xha*_*lie 6 c++ shared-ptr

C++ std::shared_ptr<..>可能为,也可能为null.这两个概念都存在,并且它们相同.此外,这两种情况之间并不总是如此.

后一种情况很容易检测,因为operator bool提供了精确的测试.根据文档,它"检查是否*this存储非空指针,即是否get() != nullptr."

是否对前一种情况进行了测试,事情是空的

我对此的使用非常简单.我有一个具有静态工厂方法的类.静态工厂方法内部是shared_ptr类的实例的静态本地,初始化为nullptr.对该工厂方法的第一次调用构造了一个类的实例,并shared_ptr在返回它的副本之前初始化静态local - 这是由a守护的mutex.这shared_ptr可以由任何东西保存,复制和传递,可以通过对静态工厂的额外调用来获取更多副本,并且最后,当所有副本被破坏时,shared_ptr删除器会破坏实例.

实例本身是使用遗留的C API创建和破坏的,由我的类包装,虽然这些实例旨在作为单例共享,但它们也需要在不再需要时进行清理 - 与单例不同.

目前,我正在使用空检查来决定是shared_ptr应该初始化静态本地还是仅复制静态本地.我担心这个测试无法检测需要重新初始化的情况 - 例如,如果某些事情在所有先前用户放弃其引用并且共享实例被删除之后的某个时间尝试获取实例.

或者shared_ptr,nullptr如果引用计数降为零并且调用了删除器,则重置为是吗?也适用于自定义删除者?

同样相关:C++中的空和空std :: shared_ptr有什么区别?

Jos*_*and 6

静态实例shared_ptr将保存一个引用,因此该对象将始终具有ref count> = 1,并且在静态清理发生之前不会被删除.正如cnettel在评论中所说,你需要std::weak_ptr在这里.

weak_ptr基本上是shared_ptr对参考计数没有贡献的.它std::shared_ptr通过该.lock()方法进行原子转换.std::shared_ptr如果未初始化,结果将转换为false,因此您知道要重新初始化(或首次初始化).

例:

std::shared_ptr<Obj> instance() {
    static std::weak_ptr<Obj> instance;
    static std::mutex lock;

    std::lock_guard<std::mutex> guard(lock);

    auto result = instance.lock();
    if (!result) {
        result = std::make_shared<Obj>();
        instance = result;
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)