在 * 现代 * C++中,我应该如何管理 *unowned* 指针?

aelbi1ox  于 2023-05-08  发布在  其他
关注(0)|答案(4)|浏览(148)

在 * 现代 * 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*,(如果有的话!)).

83qze16e

83qze16e1#

Bjarne Stroustrup有weighed in on this matter
指针非常擅长指向“事物”,而T是一个非常好的符号。指针不擅长的是表示所有权和直接支持安全迭代。
他提出两点建议:

  • T*在现代C++中的意思是“指向T的非所有指针”
  • 如果你希望你的变量声明 * 显式地记录 * 这种非所有权,请使用template<typename T> using observer_ptr = T*;
mklgxw1f

mklgxw1f2#

你的问题很大程度上是基于观点的,但我们可以看看核心指南对此有什么看法:
R.3:原始指针(T*)是非拥有的
原因
没有任何东西(在C标准或大多数代码中)可以说不是这样,大多数原始指针都是非所有的。我们希望拥有指针被识别出来,这样我们就可以可靠而有效地删除拥有指针所指向的对象。
当原始指针是一个拥有指针时,该准则提倡从不使用它。一旦你这样做了,一个原始指针也很容易发出它是非拥有的信号。这种解释的缺点是:
例外
一个主要的例外是遗留代码,特别是那些必须保持可编译为C或通过ABI与C和C风格的C
接口的代码。有数十亿行代码违反了这条禁止拥有T* 的规则,这一事实不容忽视。[...]
并不是所有的原始指针都是非拥有的,我们通常对此无能为力。然而,如果你的代码是在C++11之后编写的,那么使用一个原始指针应该足以表明它不是一个拥有指针。

kdfy810k

kdfy810k3#

这似乎是正确的,但从代码中看不出我引用了另一个对象的指针
理想情况下,它应该是显而易见的。如果指针拥有资源,那么它应该是一个智能指针。由于它不是智能指针,这意味着它不应该拥有资源。
也就是说,在现实中,有C /古代C++ /设计糟糕的接口使用拥有指针,你可以像这样澄清缺乏所有权:

class B
{
    X* _someX; // no ownership
};

也可以为此定义一个自定义类模板 Package 器,并且已经有一个proposal将这样的模板包含在标准库中,它被采用为技术规范,但尚未被采用为标准本身。据我所知,对于这种 Package 器是否有用还没有达成共识。

yhqotfr8

yhqotfr84#

https://abseil.io/tips/116是这里选项的一个很好的讨论。如果你在构建时就有了这个东西,并且从来不需要重新指向它,那么T&可能是好的。如果你不这样做,那么“hey this might be null”就是该指针的现实的一部分,T*也没问题--现代C++中的“原始”指针通常传递一个可选的、非所有的引用。

相关问题