【问题标题】:Why destructor isn't invoked?为什么不调用析构函数?
【发布时间】:2015-08-21 14:41:33
【问题描述】:
#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() 返回值为 1,因此我认为拥有该对象的最后一个 shared_ptr 将被销毁,因此将调用析构函数。但事实并非如此。任何人都可以解释为什么?如果我想保持这样的结构: 新标准::shared_ptr(新 Foo) 并且还调用了析构函数,我该怎么办? 代码只是为了好玩而写的,没有任何应用背景。

【问题讨论】:

  • 动态分配shared_ptr 绝对没有意义。

标签: c++ c++11 destructor shared-ptr weak-ptr


【解决方案1】:

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

目前还不清楚您要在这里做什么。您正在编写没有用例的奇怪、笨拙的代码,并且想知道如何“让它工作”。为了“让它工作”,编写不奇怪和不尴尬的代码。根据定义,这就是解决方案。

【讨论】:

  • “奇异”可能太弱了;)
  • 是的,我应该像这样销毁动态分配的 shared_ptr: std::shared_ptr* jack = new std::shared_ptr(new Foo);删除千斤顶;好吧,我只是四处探索,所以代码看起来很尴尬。不管怎样,你的提示对我有帮助,虽然这个问题真的很糟糕。
  • @Vito:首先不要动态分配它。
  • @LightnessRacesinOrbit “一开始就不要动态分配它。” 尤其是不使用变量来保存结果指针。
【解决方案2】:

“但事实并非如此。谁能解释为什么?”

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

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

永远不要打电话给delete(或者甚至可以这样做)。

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

【讨论】:

    【解决方案3】:

    use_count() 返回值为 1,因此我认为拥有该对象的最后一个 shared_ptr 将被销毁,因此将调用析构函数。

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

    如果我想保持这样的结构:new std::shared_ptr(new Foo) 并调用析构函数,我该怎么办?

    您必须在使用完毕后明确地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;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-21
      • 2013-08-08
      • 2021-08-04
      • 2014-03-05
      • 2018-05-24
      • 1970-01-01
      • 2021-04-01
      相关资源
      最近更新 更多