通过值或 const ref 传递 std::shared_ptr 然后存储在容器中?
Passing std::shared_ptr by value or const ref and then storing in a container?
考虑以下向量:
std::vector<std::shared_ptr<X>> myVector;
以及将给定元素添加到向量的以下两个函数:
void foo1(std::shared_ptr<X> x)
{
myVector.push_back(x);
}
void foo2(const std::shared_ptr<X>& x)
{
myVector.push_back(x);
}
我的理解是,这两个函数都将 shared_ptr
推入 X
到向量中,从而增加了 X
的引用计数。第一个函数导致引用计数的额外递增和递减,但这是不必要的。
我的理解对吗?因此,第二种选择更可取吗?
您应该将函数重写为:
void foo1(std::shared_ptr<X> x)
{
myVector.emplace_back(std::move(x));
}
void foo2(const std::shared_ptr<X>& x)
{
myVector.emplace_back(x);
}
那么这两个版本应该更高效,哪个版本取决于具体情况和特定的编译器,即使有差异,也很可能非常小。
通常最好通过引用传递共享指针,因为原子增量往往会降低性能。在你的情况下,它不会引人注意,因为无论如何你都会在之后复制它。
在 foo1
中,您按值传递参数(即共享指针)。因此,将调用 std::shared_ptr<X>
的复制构造函数(即,当在 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);
}
输出:
count in main(): 1
count in foo1(): 2
count in foo2(): 1
正如你在foo1
中看到的,不同的shared_ptr个实例的数量是2。那是main
中定义的原始shared_ptr
和[=中的副本12=]。而在 foo2
中,引用计数器保持为 1。
因此,您的推理是正确的。
考虑以下向量:
std::vector<std::shared_ptr<X>> myVector;
以及将给定元素添加到向量的以下两个函数:
void foo1(std::shared_ptr<X> x)
{
myVector.push_back(x);
}
void foo2(const std::shared_ptr<X>& x)
{
myVector.push_back(x);
}
我的理解是,这两个函数都将 shared_ptr
推入 X
到向量中,从而增加了 X
的引用计数。第一个函数导致引用计数的额外递增和递减,但这是不必要的。
我的理解对吗?因此,第二种选择更可取吗?
您应该将函数重写为:
void foo1(std::shared_ptr<X> x)
{
myVector.emplace_back(std::move(x));
}
void foo2(const std::shared_ptr<X>& x)
{
myVector.emplace_back(x);
}
那么这两个版本应该更高效,哪个版本取决于具体情况和特定的编译器,即使有差异,也很可能非常小。
通常最好通过引用传递共享指针,因为原子增量往往会降低性能。在你的情况下,它不会引人注意,因为无论如何你都会在之后复制它。
在 foo1
中,您按值传递参数(即共享指针)。因此,将调用 std::shared_ptr<X>
的复制构造函数(即,当在 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);
}
输出:
count in main(): 1
count in foo1(): 2
count in foo2(): 1
正如你在foo1
中看到的,不同的shared_ptr个实例的数量是2。那是main
中定义的原始shared_ptr
和[=中的副本12=]。而在 foo2
中,引用计数器保持为 1。
因此,您的推理是正确的。