Dan*_*vil 253 c++ boost shared-ptr c++11
当一个函数采用shared_ptr(来自boost或C++ 11 STL)时,你传递它:
通过const引用: void foo(const shared_ptr<T>& p)
或按价值:void foo(shared_ptr<T> p)?
我更喜欢第一种方法,因为我怀疑它会更快.但这真的值得吗还是还有其他问题吗?
您能否说出您选择的原因或案例,为什么您认为无关紧要.
mlo*_*kot 217
Scott,Andrei和Herb 在C++和2011年之后的Ask Us Anything会议期间讨论并回答了这个问题.观看4分34秒的性能和正确性.shared_ptr
简而言之,除非目标是共享对象的所有权(例如,在不同数据结构之间或不同线程之间),否则没有理由按值传递.
除非,您可以按照上面链接的谈话视频中的Scott Meyers所解释的那样移动优化它,但这与您可以使用的C++的实际版本有关.
在GoingNative 2012大会的交互式面板:向我们提出任何问题时,本次讨论的主要更新发生了!这值得关注,特别是从22:50开始.
小智 83
准则:除非您想使用或操纵智能指针本身,例如共享或转移所有权,否则不要将智能指针作为函数参数传递.
准则:表示函数将使用by-value shared_ptr参数存储和共享堆对象的所有权.
指南:仅使用非const shared_ptr&参数来修改shared_ptr.仅当您不确定是否要复制并共享所有权时,才使用const shared_ptr&作为参数; 否则使用widget*(或者如果不是可空的,则使用小部件&).
Nik*_*sov 36
通过const引用传递,它更快.如果您需要存储它,比如在某个容器中,请参考.计数将通过复制操作自动增加.
tcb*_*tcb 21
我运行了下面的代码,一次foo采用了shared_ptrby const&并再次foo采用了shared_ptrby值.
void foo(const std::shared_ptr<int>& p)
{
static int x = 0;
*p = ++x;
}
int main()
{
auto p = std::make_shared<int>();
auto start = clock();
for (int i = 0; i < 10000000; ++i)
{
foo(p);
}
std::cout << "Took " << clock() - start << " ms" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在我的intel core 2 quad(2.4GHz)处理器上使用VS2015,x86发布版
const shared_ptr& - 10ms
shared_ptr - 281ms
Run Code Online (Sandbox Code Playgroud)
按值复制版本的速度要慢一个数量级.
如果从当前线程同步调用函数,则更喜欢该const&版本.
Coo*_*kie 14
从C++ 11开始,你应该通过const来获取它,而不是你想象的那样.
如果您正在使用std :: shared_ptr(而不是基础类型T),那么您正在这样做,因为您想要对它执行某些操作.
如果你想将它复制到某个地方,那么通过复制更有意义,并且std ::在内部移动它,而不是通过const接受它然后再复制它.这是因为你允许调用者在调用你的函数时依次调用std :: move the shared_ptr,从而节省了一组递增和递减操作.或不.也就是说,函数的调用者可以在调用函数之后决定他是否需要std :: shared_ptr,并且取决于是否移动.如果你传递const&,这是不可能实现的,因此最好是通过值来获取它.
当然,如果调用者都需要他的shared_ptr更长时间(因此不能std :: move它)并且你不想在函数中创建一个普通的副本(假设你想要一个弱指针,或者你只是有时想要复制它,取决于某些条件),然后const&可能仍然是更可取的.
例如,你应该这样做
void enqueue(std::shared<T> t) m_internal_queue.enqueue(std::move(t));
Run Code Online (Sandbox Code Playgroud)
过度
void enqueue(std::shared<T> const& t) m_internal_queue.enqueue(t);
Run Code Online (Sandbox Code Playgroud)
因为在这种情况下,您始终在内部创建副本
Fla*_*ire 12
最近有一篇博文:https : //medium.com/@vgasparyan1995/pass-by-value-vs-pass-by-reference-to-const-c-f8944171e3ce
所以这个问题的答案是:做(几乎)从不经过const shared_ptr<T>&。
只需传递基础类即可。
基本上唯一合理的参数类型是:
shared_ptr<T> - 修改并取得所有权shared_ptr<const T> - 不要修改,拥有所有权T& - 修改,无所有权const T& - 不要修改,没有所有权T - 不要修改,没有所有权,复制便宜正如@accel 在/sf/answers/1833812851/ 中指出的,Herb Sutter 的建议是:
仅当您不确定是否要复制并共享所有权时,才使用 const shared_ptr& 作为参数
但在多少情况下你不确定?所以这是一种罕见的情况
众所周知,按值传递 shared_ptr 会产生成本,因此应尽可能避免。
大多数时候通过引用传递shared_ptr,甚至通过const引用传递更好,就可以了。
cpp核心指南对于传递shared_ptr有一个特定的规则
R.34:采用shared_ptr参数来表示函数是部分所有者
void share(shared_ptr<widget>); // share -- "will" retain refcount
Run Code Online (Sandbox Code Playgroud)
确实需要按值传递shared_ptr 的一个示例是,当调用者将共享对象传递给异步被调用者时,即调用者在被调用者完成其工作之前超出范围。被调用者必须通过按值获取 share_ptr 来“延长”共享对象的生命周期。在这种情况下,传递对shared_ptr的引用是行不通的。
将共享对象传递给工作线程也是如此。
| 归档时间: |
|
| 查看次数: |
96680 次 |
| 最近记录: |