我应该使用std :: shared指针传递指针吗?

麦可

假设我有一个由管理的对象std::unique_ptr我代码的其他部分需要访问此对象。传递指针的正确解决方案是什么?我应该只传递普通指针,std::unique_ptr::get还是应该完全使用和std::shared_ptr而不是std::unique_ptr

我有一些偏爱,std::unique_ptr因为该指针的所有者实际上负责清理。如果我使用共享指针,则即使共享对象实际被销毁,对象也可能会保持活动状态。

编辑:不幸的是,我忘了提到指针将不仅是函数调用的参数,而且还将存储在其他对象中以建立对象的网络结构。我不喜欢共享指针,因为这样一来,谁才真正拥有该对象就不再清楚了。

理查德·霍奇斯

如果未转移托管对象的所有权(并且由于它是unique_ptr,则不能共享所有权),那么将调用函数中的逻辑与所有权概念分开是更正确的。我们通过引用进行呼叫。

这是一个令人费解的说法:

鉴于:

std::unique_ptr<Thing> thing_ptr;

改变事物:

// declaration
void doSomethingWith(Thing& thing); 

// called like this
doSomethingWith(*thing_ptr);

使用事物而不修改它。

// declaration
void doSomethingWith(const Thing& thing); 

// called like this
doSomethingWith(*thing_ptr);

您唯一要unique_ptr在函数签名中提及的是,如果您要转移所有权:

// declaration
void takeMyThing(std::unique_ptr<Thing> p);

// call site
takeMyThing(std::move(thing_ptr));

您永远不需要这样做:

void useMyThing(const std::unique_ptr<Thing>& p);

之所以认为这是个坏主意,是因为如果将useMyThing的逻辑与所有权概念混淆,从而缩小了重用范围。

考虑:

useMyThing(const Thing& thing);

Thing x;
std::unique_ptr<Thing> thing_ptr = makeAThing();
useMyThing(x);
useMyThing(*thing_ptr);

更新:

注意问题的更新-存储(非所有权)对此对象的引用。

做到这一点的一种方法确实是存储一个指针。但是,指针存在逻辑错误的可能性,因为它们可以合法地为空。指针的另一个问题是,它们不能与std:: algorithms和容器很好地配合使用-需要自定义比较功能等。

有一种std::-compliant方法可以做到-std::reference_wrapper<>

所以而不是这样:

std::vector<Thing*> my_thing_ptrs;

做这个:

std::vector<std::reference_wrapper<Thing>> my_thing_refs;

由于std::reference_wrapper<T>定义了一个运算符T&,您可以reference_wrapped在任何需要一个表达式的表达式中使用该对象T

例如:

std::unique_ptr<Thing> t1 = make_thing();
std::unique_ptr<Thing> t2 = make_thing();
std::unique_ptr<Thing> t3 = make_thing();

std::vector<std::reference_wrapper<const Thing>> thing_cache;

store_thing(*t1);
store_thing(*t2);
store_thing(*t3);

int total = 0;
for(const auto& t : thing_cache) {
  total += value_of_thing(t);
}

在哪里:

void store_thing(const Thing& t) {
  thing_cache.push_back(std::cref(t));
}

int value_of_thing(const Thing& t) {
  return <some calculation on t>;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我应该对一组指针使用std :: set还是std :: unordered_set吗?

来自分类Dev

我可以使用内存映射文件传递指针吗?

来自分类Dev

我应该使用名称空间std吗?

来自分类Dev

我应该只使用 std::vector 吗?

来自分类Dev

使用shared_ptr将原始指针传递给函数

来自分类Dev

std::byte 指针应该用于指针运算吗?

来自分类Dev

我可以传递作为指针的变量的COPY吗?

来自分类Dev

我们可以在 printf 中传递指针吗?

来自分类Dev

我应该释放setlocale返回的指针吗?

来自分类Dev

我应该删除作为参数传递给函数的指针吗?

来自分类Dev

在通过引用传递之前,我们应该取消对指针的引用吗?

来自分类Dev

将 Rust 指针传递给 C 时,我应该得到 0x1 吗?

来自分类Dev

处理列表时应该使用指针吗?

来自分类Dev

我可以在所有想使用简单指针的地方使用shared_ptr吗?

来自分类Dev

我应该将printf与std :: cin混合使用吗?

来自分类Dev

std :: thread构造函数传递指针和ref传递之间有区别吗?

来自分类Dev

std :: string类成员应该是指针吗?

来自分类Dev

如何使用指针传递值?

来自分类Dev

我应该释放用于遍历链表的临时指针吗?

来自分类Dev

我应该从动态指针中删除移动吗

来自分类Dev

我可以/应该释放strtok返回的指针吗

来自分类Dev

我应该释放getfsent返回的fstab指针吗?

来自分类Dev

我可以/应该释放strtok返回的指针吗

来自分类Dev

我应该在这里使用原始指针吗?

来自分类Dev

我应该使用点(。)或箭头(->)运算符访问C ++中的指针成员吗?

来自分类Dev

我应该在返回std :: vector的函数上使用std :: move吗?

来自分类Dev

我应该在返回std :: vector的函数上使用std :: move吗?

来自分类Dev

CUDA统一内存编程-我可以将指针传递给不了解CUDA的模块吗?

来自分类Dev

在传递指向函数的指针之前,我必须始终对其进行初始化吗?

Related 相关文章

  1. 1

    我应该对一组指针使用std :: set还是std :: unordered_set吗?

  2. 2

    我可以使用内存映射文件传递指针吗?

  3. 3

    我应该使用名称空间std吗?

  4. 4

    我应该只使用 std::vector 吗?

  5. 5

    使用shared_ptr将原始指针传递给函数

  6. 6

    std::byte 指针应该用于指针运算吗?

  7. 7

    我可以传递作为指针的变量的COPY吗?

  8. 8

    我们可以在 printf 中传递指针吗?

  9. 9

    我应该释放setlocale返回的指针吗?

  10. 10

    我应该删除作为参数传递给函数的指针吗?

  11. 11

    在通过引用传递之前,我们应该取消对指针的引用吗?

  12. 12

    将 Rust 指针传递给 C 时,我应该得到 0x1 吗?

  13. 13

    处理列表时应该使用指针吗?

  14. 14

    我可以在所有想使用简单指针的地方使用shared_ptr吗?

  15. 15

    我应该将printf与std :: cin混合使用吗?

  16. 16

    std :: thread构造函数传递指针和ref传递之间有区别吗?

  17. 17

    std :: string类成员应该是指针吗?

  18. 18

    如何使用指针传递值?

  19. 19

    我应该释放用于遍历链表的临时指针吗?

  20. 20

    我应该从动态指针中删除移动吗

  21. 21

    我可以/应该释放strtok返回的指针吗

  22. 22

    我应该释放getfsent返回的fstab指针吗?

  23. 23

    我可以/应该释放strtok返回的指针吗

  24. 24

    我应该在这里使用原始指针吗?

  25. 25

    我应该使用点(。)或箭头(->)运算符访问C ++中的指针成员吗?

  26. 26

    我应该在返回std :: vector的函数上使用std :: move吗?

  27. 27

    我应该在返回std :: vector的函数上使用std :: move吗?

  28. 28

    CUDA统一内存编程-我可以将指针传递给不了解CUDA的模块吗?

  29. 29

    在传递指向函数的指针之前,我必须始终对其进行初始化吗?

热门标签

归档