3

我最近阅读了各种智能指针类型,我认为尤其是 unique_ptr 将非常有用,并且在某种程度上,shared_ptr 和weak_ptr 也是如此。但是我不确定如何创建可以处理任何一种指针类型的“通用”函数,如果这甚至是一个好主意。

所以想象有一个由智能指针封装的对象向量,你想使用一个函数对所有元素应用一些操作,如下所示:

void doSomething(vector<shared_ptr<SomeType>>& array) {
   // iterate over all array elements and do something
}

显然,您需要为 shared/unique/weak_ptr 复制此函数 3 次,这有点麻烦。拥有适合所有函数参数使用的“通用”/“多态”智能指针类型会更容易:

void doSomething(vector<generic_ptr<SomeType>>& array) {
   // iterate over all array elements and do something
   // no matter if array is a vector<shared_ptr> or vector<unique_ptr>
}

那么,是否存在这样的智能指针呢?如果是 - 使用它可能会出现哪些问题?如果没有 - 为什么不呢?

4

4 回答 4

4

不同的指针类型允许不同的所有权处理,需要不同的运行时开销。在您的情况下,您可以使用模板:

template<typename TVector>
void doSomething(TVector& array) {
   // iterate over all array elements and do something
}

并对所有智能(而不是那么智能)指针使用 commonoperator*operator->

于 2013-04-23T08:12:38.127 回答
4

一些误解会导致尴尬的代码风格:

  1. 智能指针与原始指针一样通用:在调用指向对象的函数时,您可以将它们视为相同。如果您确实需要将它们传递给采用原始指针的函数(并且这些函数不会获得所有权),您可以使用它们的get()函数为您提供该指针。见 3。

  2. 作用于集合的函数不应该将集合作为参数,而应该是一个带有一对迭代器的模板,然后可以通过取消引用迭代器指向的指针来使用它,从而为您提供对真实对象的引用。

  3. 不要编写采用原始指针的函数。改用引用并在调用站点取消引用。我知道这并不总是可能的,但大多数情况下是这样。

在函数中循环的另一种方法是使函数作用于单个对象(引用),并将循环放在调用点。C++11 让这变得非常干净:

void some_function(item_type& item); // const if necessary
for(auto&& item_ptr : collection_of_item_smart_ptrs)
  some_function(*item_ptr);

清楚地表达意图、目的和类型,没有任何句法或风格上的麻烦。

于 2013-04-23T09:17:38.607 回答
0

所有这些指针类型实际上都包装了一个裸指针。所以我们有两种情况:

  1. 您的方法以某种方式修改了指针。在这种情况下,您将无法概括它,因为它应该根据类型而有所不同。

  2. 你永远不会修改指针。只需将 const 裸指针传递给函数。

于 2013-04-23T08:15:42.350 回答
0

这些智能指针类型中的每一种都有其 onw 使用模型。

  • unique_ptr 不能放在容器中,它既不可复制也不可复制分配

  • weak_ptr 必须转换为 shared_ptr 才能访问引用的对象。例如,可用于缓存,在所有地方使用都很麻烦。

  • shared_ptr 是在你的情况下走的路

于 2013-04-23T08:16:42.397 回答