小编典典

我什么时候使用哪种指针?

all

好的,所以我最后一次以编写 C
为生,std::auto_ptr是所有可用的标准库,并且boost::shared_ptr风靡一时。我从来没有真正研究过提供的其他智能指针类型提升。我知道
C
11 现在提供了一些 boost 提出的类型,但不是全部。

那么有人有一个简单的算法来确定何时使用哪个智能指针吗?最好包括关于哑指针(原始指针,如T*)和其余 boost
智能指针的建议。(这样]()的东西会很棒。

C++11的经验法则:

按值传递,除非当

  1. 你不需要对象的所有权,一个简单的别名就可以了,在这种情况下你通过const引用传递,
  2. 你必须改变对象,在这种情况下,使用const左值引用传递,
  3. 您将派生类的对象作为基类传递,在这种情况下,您需要通过引用传递。(使用前面的规则来确定是否通过const引用传递。)

几乎从不建议通过指针传递。可选参数最好表示为std::optional(boost::optional对于较旧的标准库),并且通过引用可以很好地完成别名。

C++11 的移动语义使得按值传递和返回即使对于复杂对象也更具吸引力。


C++03的经验法则:

通过const引用传递参数,除非当

  1. 它们将在函数内部进行更改,并且此类更改应反映在外部,在这种情况下,您通过非const引用传递
  2. 该函数应该可以不带任何参数调用,在这种情况下您通过指针传递,以便用户可以传递NULL//代替0nullptr应用前面的规则来确定是否应该通过指向const参数的指针传递
  3. 它们是内置类型,可以通过复制传递
  4. 它们将在函数内部进行更改,并且此类更改不应反映在外部,在这种情况下,您可以通过副本传递(另一种方法是根据前面的规则传递并在函数内部进行复制)

(这里,“按值传递”称为“按副本传递”,因为按值传递总是在 C++03 中创建副本)


还有更多,但是这几个初学者的规则会让你走得很远。


阅读 61

收藏
2022-05-30

共1个答案

小编典典

共享所有权:
采用的标准shared_ptrBoost
对应
weak_ptr的标准几乎相同。当您需要共享资源并且不知道哪一个将是最后一个还活着时,请使用它们。用于在不影响其生命周期的情况下观察共享资源,而不是破坏循环。通常不应该发生循环-
两个资源不能相互拥有。weak_ptr``shared_ptr

请注意,Boost
还提供了shared_array,这可能是shared_ptr<std::vector<T> const>.

接下来,Boost
提供intrusive_ptr了一个轻量级的解决方案,如果您的资源已经提供了引用计数管理并且您希望将其应用于
RAII 原则。这个标准没有被采纳。

唯一所有权:*
Boost
也有一个scoped_ptr,它是不可复制的,你不能为其指定一个删除器。std::unique_ptr是类固醇,
当您需要智能指针时boost::scoped_ptr应该是您的默认选择。它允许您在其模板参数中指定删除器,并且是 可移动 的,与.
只要您不使用需要可复制类型的操作(显然),它也可以在 STL 容器中完全使用。
* __boost::scoped_ptr

再次注意,Boost
有一个数组版本:scoped_array,标准通过要求std::unique_ptr<T[]>部分特化来统一它,它将delete[]指针而不是deleteing
它(使用default_deleter)。std::unique_ptr<T[]>还提供operator[]代替operator*and
operator->

请注意,std::auto_ptr它仍在标准中,但已 弃用搂D.10 [depr.auto.ptr]

类模板auto_ptr已弃用。[ 注: 类模板unique_ptr(20.7.1)提供了更好的解决方案。 ”第二注 ]

无所有权:
使用哑指针(原始指针)或对资源的 非拥有引用的引用 ,并且当您知道该 资源将比
引用对象/范围更长时。当您需要可空性或可重置性时,首选引用并使用原始指针。

如果您想要对资源的非拥有引用,但您不知道该资源是否会比引用它的对象寿命长,请将资源打包shared_ptr并使用 a weak_ptr-
您可以测试父级shared_ptr是否存在于lock,这将如果资源仍然存在,则返回shared_ptr非空值。如果要测试资源是否已死,请使用expired.
两者可能听起来很相似,但在并发执行方面却有很大不同,因为expired只保证了它对单个语句的返回值。一个看似无辜的测试

if(!wptr.expired())
  something_assuming_the_resource_is_still_alive();

是一个潜在的竞争条件。

2022-05-30