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