通过值或 const ref 传递 std::shared_ptr 然后存储在容器中?

ksl*_*ksl 7 c++ reference-counting pass-by-value shared-ptr pass-by-const-reference

考虑以下向量:

std::vector<std::shared_ptr<X>> myVector;
Run Code Online (Sandbox Code Playgroud)

以及以下两个将给定元素添加到向量的函数:

void foo1(std::shared_ptr<X> x)
{
    myVector.push_back(x);
}

void foo2(const std::shared_ptr<X>& x)
{
    myVector.push_back(x);
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,这两个函数都将 a 推shared_ptrX向量中,从而增加 的引用计数X。第一个函数导致引用计数的额外递增和递减,但这是不必要的。

我的理解正确吗?那么第二种选择是否更可取呢?

101*_*010 5

您可以foo1按值传递参数(即共享指针)。std::shared_ptr<X>因此,将调用 的复制构造函数(即,当在}of调用本地复制的析构函数时,引用计数器将先增加然后减少foo1)。

通过foo2引用传递参数(即共享指针)const。因此,您传递const原始对象的限定别名(即,引用计数器不会增加)。

您还可以在以下示例中看到这一点:

struct X {};

void foo1(std::shared_ptr<X> x) { 
  std::cout << "count in foo1(): " << x.use_count() << std::endl;
}

void foo2(const std::shared_ptr<X>& x) {
  std::cout << "count in foo2(): " << x.use_count() << std::endl;
}

int main() {
  std::shared_ptr<X> x(new X);
  std::cout << "count in main(): " << x.use_count() << std::endl;
  foo1(x);
  foo2(x);
}
Run Code Online (Sandbox Code Playgroud)

输出:

count in main(): 1
count in foo1(): 2
count in foo2(): 1
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,不同的shared_ptr实例的数量是2。这是在中定义的foo1原始实例和在中的副本。而参考计数器中的值仍为 1。shared_ptrmainfoo1foo2

因此,你的推理是正确的。