![](/img/trans.png)
[英]Is it threadsave to pass shared_pointer by const reference?
[英]Why do we need to pass const shared pointer as reference?
在阅读开源代码时,我发现以下内容以两种不同的方式将共享指针传递给函数。
class A{A();};
typedef std::shared_ptr<A> A_Ptr;
void func1(A_Ptr a);
void func2( const A_Ptr& a);
使用 const 时将其作为引用传递的原因是什么? 我了解 func2 的作者不希望该函数能够更改 a.c 中的任何内容。 但是我们不能只做这个const A_Ptr a
吗? 另外,我们不应该在 func1 中使用A_Ptr & a
传递它的原因是什么?
代码中出现上述情况:
Git: https : //github.com/uzh-rpg/rpg_svo/
void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame)
但是我们不能只做这个
const FramePtr
框架吗?
当然,我们可以,但是随后会调用复制构造函数,这对于较大的类型(任何大于内置类型的类型)通常比通过引用传递更昂贵。 这不是shared_ptr
特有的。 如果您不需要副本并且不想更改它们,那么通过 const 引用传递任何对象通常应该是您的默认设置。 只有像 int、float 或 char 这样的内置类型才应该按值传递。
更有趣的是为什么func1
使用副本。 最可能的情况是他无论如何都需要一个副本,因为他想在类中保留一个引用。 我在您发布的 github 存储库中找不到您引用的确切文件。 如果还不清楚,请将 func1 的函数体传递到问题中。
编辑:啊,我明白了。 看起来他在这里传递值的原因更多地与线程安全有关。 没有阅读整个内容,但如果他通过常量引用传递,则拥有的线程可能会删除shared_ptr
。
例如, func 需要按值传递,否则主线程可能会删除指针。 可能是这样的,但更复杂:
#include <chrono>
#include <iostream>
#include <memory>
#include <thread>
using namespace std::chrono_literals;
struct S {
S() {}
};
void
//This signature would be false
//func(std::shared_ptr<S> const& s)
func(std::shared_ptr<S> s)
{
std::cout << s.use_count() << '\n';
std::this_thread::sleep_for(2s);
//use_count would be 0 here if we pass by reference
std::cout << s.use_count() << '\n';
}
int
main(int argc, char**) {
std::shared_ptr<S> s{std::make_shared<S>()};
std::thread t{func, std::ref(s)};
std::this_thread::sleep_for(1s);
s.reset();
t.join();
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.