首页 > 解决方案 > reference to std::shared:ptr to avoid reference counting

问题描述

I am often facing the argument, that by accepting a const std::shared_ptr<T>& one can avoid the reference count increment:

void foo(std::shared_ptr<const int> p); 
void foo2(const std::shared_ptr<const int>& p); 

int main(){
   std::shared_ptr<const int> a = std::make_shared<int>(3);

   foo(a);  // calling this function always does reference counting (atomic locks...)
   foo2(a); // calling this function elides reference counting

   std::shared_ptr<int> b = std::make_shared<int>(3);;
   foo2(b); // what happens here? since there is a cast involved creating a temporary ... (NRVO??)
}

But I assume that when calling foo2(b) reference counting is not elided? However, can the compiler or the std-implementation somehow elide reference counting. Would it make it any better if foo2(std::move(b)) would be called, for this elision to happen?

标签: c++c++11c++17shared-ptrc++20

解决方案


是的,在进入之前必然会增加引用计数foo2,退出时会减少。这是因为参数const std::shared_ptr<const int>& p必须引用 type 的不同对象std::shared_ptr<const int>,因此必须构造和销毁临时对象。

在该语言中,不可能省略此引用计数,因为如果在参数b执行期间修改foo2了参数,则p必须保持不受影响;它必须继续指向int堆上的同一个对象,该对象可以被修改但不能被删除。(这不适用于foo2用 调用时a,因为在这种情况下p直接指的是a,而不是临时的,因此a通过 可以看到对 的修改p。)

传递std::move(b)tofoo2不是一个好主意,因为当临时绑定到被破坏时,这将b留空并删除对象。intp


推荐阅读