在 modern C++ 中,我应该如何管理 unowned 指针? 我在想类似
weak_ptr
代表 unique_ptr
,但这似乎不存在。
例如,如果我有一个类
A
拥有一个指针,我应该使用 unique_ptr<X>
而不是旧的 X*
指针,例如
class A
{
std::unique_ptr<X> _myX;
};
但是如果我有另一个类
B
使用这个指针,我在这里该怎么办?使用 C 风格指针我会这样做:
class B
{
X* _someX;
};
这似乎是正确的,但从代码中并不明显看出我引用了另一个对象的指针(例如读者可能认为我可以不使用智能指针)。
std::shared_ptr<X>
- 似乎浪费了引用计数,因为 A
保证比 B
更长寿。std::weak_ptr<X>
- 仅适用于 shared_ptr
X&
- 仅当 X& 在 B 的构造函数中可用时才有效这似乎是一个明显的问题,如果之前有人问过这个问题,我们深表歉意。我环顾四周,看到了 this 问题,但不幸的是,OP 在一种特定情况下询问“可以使用 X* 吗”。我正在寻找我通常应该做什么而不是X*,(如果有的话!)。
对此事进行了权衡。
指针非常擅长指向“事物”,而他提出两个建议:T* 是一个非常好的表示法……指针不擅长的是代表所有权
T*
在现代 C++ 中表示“指向
T
的非拥有指针”
这种非所有权,请使用
template<typename T> using observer_ptr = T*;
。
这似乎是正确的,但从代码中并不明显看出我引用了另一个对象的指针理想情况下,它
应该是显而易见的。如果指针拥有资源,那么它应该是一个智能指针。由于它不是智能指针,这意味着它不应该拥有该资源。
也就是说,在现实中,C /古老的C ++ /设计糟糕的接口使用拥有指针,你可以像这样澄清缺乏所有权:
class B
{
X* _someX; // no ownership
};
提案将此类模板包含在标准库中,该提案已被采纳为技术规范,但尚未被采纳为标准本身。据我了解,对于这种包装器是否有用还没有达成共识。
原因该指南提倡在原始指针是拥有指针时永远不要使用它。一旦你这样做了,原始指针也很容易表明它是非拥有的。这种解释的缺点是:(在 C++ 标准或大多数代码中)没有什么可说的,并且大多数原始指针都是非拥有的。我们希望识别出拥有指针,以便我们能够可靠且高效地删除拥有指针所指向的对象。
异常并非所有原始指针都是非拥有的,并且通常我们对此无能为力。但是,如果您的代码是在 C++11 之后编写的,那么使用原始指针应该足以表明它不是拥有指针。主要的一类例外是遗留代码,尤其是必须保持可编译为 C 或通过 ABI 与 C 和 C 风格的 C++ 接口的代码。事实上,有数十亿行代码违反了禁止拥有 T* 的规则,这一事实不容忽视。 [...]
https://abseil.io/tips/116 这里对选项进行了很好的讨论。如果您在构建时就有了该东西,并且永远不需要重新指向它,那么 T&
可能会很好。如果你不这样做,那么“嘿,这可能是 null”是该指针现实的一部分,并且
T*
很好 - 现代 C++ 中的“原始”指针通常传达一个可选的、非拥有的引用。