我有这段代码:
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
use_count: 1
dtor called
然而,我预计会发生这种情况:
ctor called
thread1 quitting
dtor called
use_count: 0
因为我认为通过引用传递shared_ptr不会增加其引用计数,因此一旦thread1超出范围,托管对象就会被销毁。你能告诉我为什么我错了吗?感谢。
答案 0 :(得分:1)
您声明lambda采用shared_ptr
引用,但std::thread
的构造函数默认复制所有参数。
如果你逐步调用析构函数,你会发现在原始文件被销毁之前,它的使用次数是短暂的2。
要将shared_ptr作为参考传递,您可以使用std::ref
:
std::thread thread2([]{/*...*/}, std::ref(ptr));
这将为您提供ptr
超出范围的预期行为,这意味着无论如何都要在访问它时调用未定义的行为。