通过引用传递shared_ptr

时间:2013-11-29 02:38:27

标签: 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);
        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超出范围,托管对象就会被销毁。你能告诉我为什么我错了吗?感谢。

1 个答案:

答案 0 :(得分:1)

您声明lambda采用shared_ptr引用,但std::thread的构造函数默认复制所有参数。

如果你逐步调用析构函数,你会发现在原始文件被销毁之前,它的使用次数是短暂的2。

要将shared_ptr作为参考传递,您可以使用std::ref

std::thread thread2([]{/*...*/}, std::ref(ptr));

这将为您提供ptr超出范围的预期行为,这意味着无论如何都要在访问它时调用未定义的行为。