C++ 通过引用传递共享\u ptr
我有一段代码:C++ 通过引用传递共享\u ptr,c++,C++,我有一段代码: class A { public: A() { std::cout << "ctor called\n"; } ~A() { std::cout << "dtor called\n"; } }; int main() { std::thread thread1([]{ std::shared_ptr<A> ptr(new A);
class A
{
public:
A()
{
std::cout << "ctor called\n";
}
~A()
{
std::cout << "dtor called\n";
}
};
int main()
{
std::thread thread1([]{
std::shared_ptr<A> ptr(new A);
std::thread thread2([](std::shared_ptr<A>& arg){
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "use_count: " << arg.use_count() << std::endl;
},ptr);
thread2.detach();
std::cout << "thread1 quitting\n";
});
thread1.detach();
while (1);
return 0;
}
然而,我预计会发生这种情况:
ctor called
thread1 quitting
dtor called
use_count: 0
因为我认为通过引用传递共享的_ptr不会增加其ref计数,因此一旦thread1超出范围,托管对象就会被销毁。你能告诉我为什么我错了吗?谢谢。您声明lambda采用
共享\u ptr
引用,但是std::thread
的构造函数默认复制所有参数
如果您单步遍历被调用的析构函数,您将看到它的使用计数在原始函数被销毁之前短暂地为2
要将共享的ptr作为引用传递,可以使用std::ref
:
std::thread2([]{/*…*/},std::ref(ptr))代码>
这将为您提供超出范围的ptr
预期行为,这意味着您在访问它时调用了未定义的行为。谢谢!我得到了预期的结果。您能解释一下模板magic std::ref()的作用吗?我尝试了std::shared\u ptr&ref=ptr编码>并将引用传递给thread2。它也没用。使用std::ref
将导致未定义的行为,因为共享指针超出范围,使用该引用将是不好的。@DaveS感谢您的提醒。我只是测试共享的线程安全性…@melak47:std::ref
根本不与弱计数交互。它创建了一个具有到引用的隐式转换的结构。您仍在使用对现在已销毁的共享\u ptr
的引用。内存可能仍然存在或具有正常值这一事实与此无关。
ctor called
thread1 quitting
dtor called
use_count: 0