mirror of
https://github.com/CnTransGroup/EffectiveModernCppChinese.git
synced 2025-02-05 00:30:31 +08:00
Update item20.md
Co-authored-by: Yang Yi <qingfeng.yy@alibaba-inc.com>
This commit is contained in:
parent
445e2aea12
commit
167462f4e0
@ -76,7 +76,7 @@ std::shared_ptr<const Widget> fastLoadWidget(WidgetID id)
|
||||
有三种选择:
|
||||
|
||||
- **原始指针**。使用这种方法,如果`A`被销毁,但是`C`继续指向`B`,`B`就会有一个指向`A`的悬空指针。而且`B`不知道指针已经悬空,所以`B`可能会继续访问,就会导致未定义行为。
|
||||
- **`std::shared_ptr`**。这种设计,`A`和`B`都互相持有对方的`std::shared_ptr`,导致的`std::shared_ptr`环状结构(`A`指向`B`,`B`指向`A`)阻止`A`和`B`的销毁。甚至`A`和`B`无法从其他数据结构被访问了(比如,`C`不再指向`B`),每个的引用计数都还是1。如果发生了这种情况,`A`和`B`都被泄漏:程序无法访问它们,但是资源并没有被回收。
|
||||
- **`std::shared_ptr`**。这种设计,`A`和`B`都互相持有对方的`std::shared_ptr`,导致的`std::shared_ptr`环状结构(`A`指向`B`,`B`指向`A`)阻止`A`和`B`的销毁。甚至`A`和`B`无法从其他数据结构访问了(比如,`C`不再指向`B`),每个的引用计数都还是1。如果发生了这种情况,`A`和`B`都被泄漏:程序无法访问它们,但是资源并没有被回收。
|
||||
- **`std::weak_ptr`**。这避免了上述两个问题。如果`A`被销毁,`B`指向它的指针悬空,但是`B`可以检测到这件事。尤其是,尽管`A`和`B`互相指向对方,`B`的指针不会影响`A`的引用计数,因此在没有`std::shared_ptr`指向`A`时不会导致`A`无法被销毁。
|
||||
|
||||
使用`std::weak_ptr`显然是这些选择中最好的。但是,需要注意使用`std::weak_ptr`打破`std::shared_ptr`循环并不常见。在严格分层的数据结构比如树中,子节点只被父节点持有。当父节点被销毁时,子节点就被销毁。从父到子的链接关系可以使用`std::unique_ptr`很好的表征。从子到父的反向连接可以使用原始指针安全实现,因为子节点的生命周期肯定短于父节点。因此没有子节点解引用一个悬垂的父节点指针这样的风险。
|
||||
|
Loading…
Reference in New Issue
Block a user