C ++ std::shared_ptr<..>
可能为空,也可能是 null 。这两个概念都存在,并且它们不等价。此外,这两种情况之间都没有任何暗示。
后一种情况很容易被发现,因为operator bool
正好提供了这种测试。根据文档,它“检查*this
是否存储非空指针,即是否get() != nullptr
。”
是否对前一种情况进行了测试,事情为空的情况?
我对此的使用非常简单。我有一个具有静态工厂方法的类。静态工厂方法内部是类的实例的静态本地shared_ptr
,初始化为nullptr
。对此工厂方法的第一次调用构造了一个类的实例,并在返回它的副本之前初始化静态本地shared_ptr
- 这由mutex
保护。 shared_ptr
可能由任何东西持有,复制和传递,可以通过额外调用静态工厂获取更多副本,最后,当所有副本被破坏时,shared_ptr
的删除器会破坏实例。
实例本身是由遗留的C API创建和破坏的,由我的类包装,虽然这些实例旨在作为单例共享,但它们也需要在不再需要时进行清理 - 与单例不同
目前,我正在使用空检查来确定是应该初始化静态本地shared_ptr
还是仅复制静态本地shared_ptr
。我担心这个测试无法检测需要重新初始化的情况 - 例如,如果某些东西试图在所有先前用户放弃他们的引用并且共享实例被删除之后的某个时间获取实例。
或者,当引用计数降为零并且调用删除器时,nullptr
是否重置为{{1}}?也适用于自定义删除者?
也相关:What is the difference between an empty and a null std::shared_ptr in C++?
答案 0 :(得分:6)
shared_ptr
的静态实例将包含引用,因此该对象将始终具有引用计数&gt; = 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;
}