为什么不调用析构函数?

Why destructor isn't invoked?

#include <memory>
#include <iostream>


struct Foo {
    Foo() { std::cout << "Constructor ...\n"; }
    void doSth() {std::cout << "hi" << std::endl;}
    ~Foo() { std::cout << "Destructor ...\n"; }
};


int main() {


   {std::weak_ptr<Foo> jack = (*(new std::shared_ptr<Foo>(new Foo)));

    std::cout << (jack).use_count() << std::endl;
    // std::shared_ptr<Foo> ptr = jack.lock();
    // std::cout << ptr.use_count() << std::endl;
  }
}

use_count() return 值为 1,因此我认为拥有该对象的最后剩余 shared_ptr 将被销毁,因此将调用析构函数。但事实并非如此。有大佬能解释一下为什么吗?如果我想维护这样的结构: 新 std::shared_ptr(新富) 并且还调用了析构函数,我该怎么办? 代码纯属娱乐,没有任何应用背景

奇怪的是,您动态分配了 shared_ptr,并且从未采取任何措施来销毁它。如果 shared_ptr 没有被销毁,它指向的东西也不会被销毁。

真的不清楚你想在这里做什么。您正在编写没有用例的奇怪、笨拙的代码,并且想知道如何 "make it work"。好吧"make it work",写出不陌生不尴尬的代码。根据定义,这就是解决方案。

"But it isn't the case. Can any guy explain why?"

您正在丢失对使用 (sub) 表达式创建的指针的引用

new std::shared_ptr<Foo>(new Foo))

永远不要在上面调用 delete(甚至不能调用)。

因此它有自己的析构函数,并且永远不会调用包装类型的析构函数。

The use_count() return value is 1, therefore I think the last remaining shared_ptr owning the object will be destroyed and the destructor will therefore be invoked.

在这种情况下情况并非如此,因为您正在动态分配 shared_ptr 并且永远不会销毁它weak_ptr 不会破坏它所指的 shared_ptr 。当您调用 lock() 获取新的 shared_ptr 时,共享对象的 use_count() 递增到 2,然后当 shared_ptrfrom lock() 变为 1 时递减到 1正如预期的那样,超出范围。但是 use_count() 仍然 > 0 因为第一个 shared_ptr 仍然在堆内存中徘徊。 shared_ptr 本身没有引用计数,你仍然必须像其他 class 一样分配和销毁它。它只管理它共享的对象的引用计数。

If I want to maintain the structure like this: new std::shared_ptr(new Foo) and also have the destructor invoked, what should I do?

你必须明确地 delete shared_ptr 当你用完它时:

int main()
{
    std::shared_ptr<Foo> *jill = new std::shared_ptr<Foo>(new Foo);

    {
    std::weak_ptr<Foo> jack = *jill;

    std::cout << jack.use_count() << std::endl;
    // std::shared_ptr<Foo> ptr = jack.lock();
    // std::cout << ptr.use_count() << std::endl;
    }

    delete jill;
    return 0;
}

这完全违背了 shared_ptr 的初衷。您需要按照预期的方式使用它:

int main()
{
    std::shared_ptr<Foo> jill(new Foo);
    //std::shared_ptr<Foo> jill = std::make_shared<Foo>();

    std::weak_ptr<Foo> jack = jill;

    std::cout << jack.use_count() << std::endl;
    // std::shared_ptr<Foo> ptr = jack.lock();
    // std::cout << ptr.use_count() << std::endl;

    return 0;
}