我应该通过引用传递shared_ptr吗? [英] Should I pass a shared_ptr by reference?

查看:152
本文介绍了我应该通过引用传递shared_ptr吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

传递shared_ptr的最佳做法是什么?



目前我传递的shared_ptr函数参数如下:

  void function1(shared_ptr< TYPE>& value); 


解决方案

在受控情况下, em>常数参考。确保没有人在同时删除对象,但如果你谨慎对待给予引用的对象,这不应太难。



一般来说,你应该将共享指针作为直接复制传递。这给出了它的意图语义:每个包含共享指针的副本的范围由于它在所有权中的共享而保持对象活着。



唯一的原因不总是传递值的价值是复制一个共享的指针以一定的价格,由于原子引用计数更新;



由于主要问题已经得到回答,或许有必要考虑一下您应该从不使用共享指针的几种方法。这里是一个小思想实验。让我们定义一个共享指针类型 SF = std :: shared_ptr< Foo> 。为了考虑引用,而不是传递函数参数,让我们看看类型 RSF = std :: reference_wrapper< T> 。也就是说,如果我们有一个共享指针 SF p(std :: make_shared< Foo>()); ,那么我们可以使用值语义通过 RSF w = std :: ref(p); 。这么多的设置。



现在,大家都知道指针的容器是雷区。所以 std :: vector< Foo *> 将是一个噩梦维护,任何数量的错误产生于不正确的生命周期管理。在概念上更糟糕的是,它永远不清楚谁拥有其容器存储的指针的对象。指针甚至可以是指向动态对象,自动对象和垃圾的指针的混合。没有人能告诉。所以标准的解决方案是使用 std :: vector< SF> 。这是使用共享指针的正确方法。另一方面,你不能使用的是 std :: vector< RSF> - 这是一个难以管理的怪物,其实是非常类似于裸指针的原始向量!例如,不清楚您持有引用的对象是否仍然活着。



对于第二个例子,假设我们有一个共享指针 SF p 如前。现在我们有一个函数 int foo(SF),我们要同时运行。通常的 std :: thread(foo,p)工作正常,因为线程构造函数对其参数进行复制。但是,如果我们说 std :: thread(foo,std :: ref(p)),我们会遇到各种麻烦:范围可能会过期并销毁对象,你会留下一个悬空的引用和一个无效的指针!



我希望这两个公认的设计示例脱落了一点光当你真正想要通过 copy 传递共享指针时。在一个精心设计的程序中,应该始终清楚谁负责哪些资源,如果使用正确,共享指针是一个伟大的工具。


What are the best practices for passing a shared_ptr?

Currently I pass shared_ptr function arguments like so:

void function1( shared_ptr<TYPE>& value );

解决方案

In controlled circumstances you can pass the shared pointer by constant reference. Be sure that nobody is concurrently deleting the object, though this shouldn't be too hard if you're careful about to whom you give references.

In general, you should pass the shared pointer as a straight copy. This gives it its intended semantics: Every scope that contains a copy of the shared pointer keeps the object alive by virtue of its "share" in the ownership.

The only reason not to always pass by value is that copying a shared pointer comes at a certain price on account of the atomic reference count update; however, this might not be a major concern.


Optional digression:

Since the main question has been answered, perhaps it is instructive to consider a few ways in which you should never use a shared pointer. Here is a little thought experiment. Let us define a shared pointer type SF = std::shared_ptr<Foo>. In order to consider references, rather than passing function arguments let us look at the type RSF = std::reference_wrapper<T>. That is, if we have a shared pointer SF p(std::make_shared<Foo>());, then we can make a reference wrapper with value semantics via RSF w = std::ref(p);. So much for the setup.

Now, everybody knows that containers of pointers are minefield. So std::vector<Foo*> will be a nightmare to maintain, and any number of bugs arise from improper lifetime management. What's worse conceptually is that it is never clear who owns the objects whose pointers the container stores. The pointers could even be a mix of pointers to dynamic objects, automatic objects, and garbage. Nobody can tell. So the standard solution is to use std::vector<SF> instead. This is The Right Way to use the shared pointer. On the other hand, what you must never use is std::vector<RSF> -- this is an unmanageable monster that is actually very similar to the original vector of naked pointers! For example, it's not clear whether the object to which you hold a reference is still alive. Taking a reference of the shared pointer has defeated its entire purpose.

For a second example, suppose we have a shared pointer SF p as before. Now we have a function int foo(SF) that we want to run concurrently. The usual std::thread(foo, p) works just fine, since the thread constructor makes a copy of its arguments. However, had we said std::thread(foo, std::ref(p)), we'd be in all sorts of trouble: The shared pointer in the calling scope could expire and destroy the object, and you would be left with a dangling reference and an invalid pointer!

I hope these two admittedly fairly contrived examples shed a bit of light on when you really want your shared pointers to be passed around by copy. In a well-designed program, it should always be clear who is responsible for which resources, and when used right, the shared pointer is a great tool for the job.

这篇关于我应该通过引用传递shared_ptr吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆