c++ - std::shared_ptr 为空但不为空
问题描述
std::shared_ptr<T>
别名构造函数让我们玩有趣的游戏。上面的 SO 帖子讨论了第一个参数何时为std::shared_ptr<void>{nullptr}
. 我对反向感兴趣。即使shared_ptr
“是” nullptr
(如果不是我们保留对它的引用,这将是完全无法访问的),这是否保证保持指向对象的活动?:
std::shared_ptr<S> ps = std::make_shared<S>();
auto& s = *ps; // Keep a reference to the S.
auto p = std::shared_ptr<S>(ps, nullptr); // Aliasing c'tor with null pointer.
ps = nullptr;
assert(ps == nullptr);
assert(p == nullptr);
foo(s); //< Is the S still alive here?
解决方案
是的,“空但不为空”shared_ptr
将使对象保持活动状态,因为它与shared_ptr
构造它的对象共享所有权。所有shared_ptr
彼此共享所有权的 s 都会对存储在控制块中的原子引用计数做出贡献,并且只有当该引用计数达到零时,才会销毁拥有的对象。
对于标准语,请参阅 [util.smartptr.shared.const]/14:
template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
构造一个shared_ptr
存储p
和共享所有权的实例r
没有对p
;的值指定任何约束。因此,它可能是任何有效的指针值,包括 null 甚至是结束指针(尽管我不确定您为什么要这样做)。
然后看[util.smartptr.shared.dest]/(1.1):
如果
*this
为空或与另一个shared_ptr
实例共享所有权 (use_count() > 1
),则没有副作用。
换句话说,当ps
被销毁时,它仍然与 共享所有权p
,因此该对象还没有被销毁。
生成的对象在通常意义上并不是真的无法到达,因为它仍然可以销毁它。你不能用它做任何其他事情。
推荐阅读
- java - 在android studio中无缘无故面对null
- python - 如何从字典创建数据框
- logging - 如何从 splunk 下载原始日志文件
- c# - 使用 Range.PasteAndFormat c# 时粘贴项目的顺序
- java - Java 代码生成中用于包的 Swagger-CodeGen 标记
- sql-server - 通过链接服务器从 SQL 服务器调用带有输出参数的 Oracle 存储过程
- java - 你如何使用'''public static void main(double[] args)'''中的变量?
- swift - swift中的多个if let和OR条件
- apache-kafka - 与 Kafka 连接器通信
- three.js - ThreeJS:第一次着色器尝试 - 混合两个纹理