【问题标题】:Will the smart pointer or scoped pointers delete an object when the class has no destructor当类没有析构函数时,智能指针或作用域指针会删除对象吗
【发布时间】:2012-02-24 07:28:04
【问题描述】:

当类没有析构函数时,智能指针或作用域指针是否会删除对象 如果没有,为什么不离开范围,让对象自己删除呢?

【问题讨论】:

  • “被自己删除”是什么意思?
  • 如果没有明确编写析构函数,C++ 将为您创建一个默认析构函数。所以智能指针总会有一个析构函数可以调用。

标签: c++ smart-pointers


【解决方案1】:

删除实例时,即使您没有析构函数,也会删除所有类成员。处理指针时会发生内存泄漏:

class A
{
private:
   B* b;
};

在这种情况下,b 本身会在A 的实例被删除时被销毁,但它指向的内存不会。

class A
{
private:
   SmartPtr<B> b;
};

在智能指针的情况下,通常在析构函数中有一些引用计数和内存清理,它指向的内存会被它的析构函数显式销毁,而智能指针的析构函数会在实例时被隐式调用包含的类被销毁。

【讨论】:

    【解决方案2】:
    【解决方案3】:

    是的,无论类是否具有析构函数,智能指针都会删除对象。请注意,智能指针用于堆上分配的对象(使用new),并且这些对象在超出范围时不会释放内存,您需要显式地delete 它们。智能指针将移除显式删除它们的过程。

    【讨论】:

      【解决方案4】:

      指向对象本身的指针将被删除。但是,如果类中有任何动态分配的数据,它将不会被释放。拥有析构函数的想法是能够对类对象进行后处理,主要是释放所占用的任何资源。

      【讨论】:

        【解决方案5】:

        new 和 delete 做两件事。

        new 分配内存并获取一个对象以在该内存空间中构造自己。 delete 先让对象自毁,然后释放内存。

        请注意,可以为某些智能指针提供自定义删除器,该删除器不会在对象上调用 delete,但无论您要求它做什么。有时您可能希望将其传递为空操作。

        【讨论】:

          【解决方案6】:

          你的观点很好;智能指针的用途并不多 在 C++ 中,因为大多数时候它们可能是相关的,所以你会 最好使用值语义和复制。如果是 scoped_ptr,最常使用的是实际对象为 多态:

          scoped_ptr<Base> pObj = condition 
                                  ? static_cast<Base*>( new Derived1 )
                                  : static_cast<Base*>( new Derived2 );
          

          (很遗憾,至少需要static_cast 之一。)

          如果您要处理多态对象的容器,则需要 shared_ptr 相反,如果您要返回多态对象,或者 否则传递它,如果可以的话,你将使用unique_ptr 保证它的可用性,否则auto_ptr——在某些情况下 在你传递它的地方,shared_ptr 可能更合适。

          在返回或传递对象的情况下,成本 复制它也可能是使用智能指针的动机,即使 对象不是多态的。在这种情况下,我仍然会使用值语义 (即复制和分配对象本身)除非我有 性能问题。

          请注意,智能指针不仅仅用于内存管理。一世 线程间队列接口中经常使用auto_ptr: 一旦对象被插入到队列中,它就不再属于 到发送线程; auto_ptr 准确地表达了这些语义, 发送线程中的auto_ptr 变得无效。或者一个 可修改的单例(应该非常非常罕见的东西)可能 在其instance 函数中获取锁,并返回shared_ptr 它释放了最终析构函数中的锁。我也用过smart 一种或两种情况下的指针以确保事务语义:在一种情况下 例如,对象位于许多不同的集合中(其中 当然,持有指向它们的指针),根据不同的排序 标准。要修改一个对象,你需要一个指向它的共享指针;这 返回此共享指针的函数也删除了对象 从集合中,以便您也可以安全地修改键值, 最后的析构函数根据 新钥匙。等等——smart 有很多用途 与内存管理或对象无关的指针 终生。

          【讨论】:

            猜你喜欢
            • 2012-09-10
            • 1970-01-01
            • 2012-04-17
            • 2010-10-15
            • 2011-04-06
            • 2012-12-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多