【问题标题】:Why are destructors required in C++?为什么 C++ 中需要析构函数?
【发布时间】:2008-12-13 11:05:46
【问题描述】:

当指针超出范围时,它的内存被释放,那么为什么在 c++ 中创建destructors?

【问题讨论】:

    标签: c++


    【解决方案1】:

    如果您要问为什么 C++ 类有析构函数,有些类的要求不仅仅是释放内存。例如,您可能有一个对象分配了一个需要彻底关闭的套接字连接。

    此外,“取消作用域”指针不会释放它指向的内存,因为其他指针可能正在引用它。

    如果堆栈上有指针,退出函数将释放指针使用的内存,但不会释放指针指向的内存。有一个微妙但非常重要的区别。

    【讨论】:

      【解决方案2】:

      当指针超出范围时,指针占用的内存被释放。指针占用的 4 或 8 个字节(通常)的内存,即。

      指针指向的对象(或其他内存)在指针超出范围时被释放。您可以通过删除指针来做到这一点。如果有的话,它会调用析构函数。

      【讨论】:

        【解决方案3】:

        首先,您错误地声明当指针超出范围时内存被释放。如果原始指针为假,则内存会丢失,指向的对象所持有的任何资源也会随之丢失。

        析构函数是该语言的核心特性,也是RAII 资源管理习语的基础。对象在构造过程中获取资源并在析构函数中释放相同的资源。它是一种简单、可控、简单的资源管理方法。请注意,资源是内存中的任何内容(智能指针析构函数释放它们控制的内存,容器释放它们的内部内存结构)或任何其他资源(ofstreams 释放打开的文件,数据库连接释放套接字)。

        虽然 C# 或 Java 等托管语言的内存是由垃圾收集器自动释放的,但只有内存才会被释放,用户不得不在使用位置手动控制所有其他资源。

        如果您检查 C#/Java 中的异常控制结构,您会注意到 C++ 中不存在 finally 子句。原因是托管语言必须为用户提供一个保证执行的代码块,以便手动释放资源。释放资源的压力由使用库的程序员承担。

        在 C++ 中,使用 RAII 习语,每个对象都对其持有的资源负责,并且必须在销毁期间释放它们。这意味着如果您使用堆栈中的对象,资源将在没有用户交互的情况下被释放。控制资源的责任在类中,用户千万不要记得手动释放每个资源。

        许多托管语言被告很高兴地说,不必记住何时何地释放内存,因为它会被垃圾收集器声明是一个很大的优势,但他们不会讨论如何控制其他资源。内存管理只是资源管理问题的一个子集,同样的解决方案也适用。如果您将内存保存在智能指针中(std::auto_ptr、boost::shared_ptr、std::tr1::unique_ptr、std::tr1::shared_ptr...,选择适合您使用的那个),那么内存将被管理给你。

        虽然这篇文章似乎偏离了最初的析构函数问题,但它确实非常密切相关。所有资源控制必须在析构函数中执行,这就是智能指针的工作方式:当堆栈分配的智能指针超出范围时,析构函数被调用并检查是否必须释放堆(新)分配的内存,如果是,delete 被调用。但话又说回来,这只是更一般问题的一个子集。

        【讨论】:

          【解决方案4】:

          当有一个指针(作为类成员存在)时,应该有一个该类的析构函数应该删除指针成员指向的对象。 如果你有 smart_pointer 代替类中的指针,那么就不需要析构函数。

          下面的 qn 将帮助您更好地理解。 Will the below code cause memory leak in c++

          【讨论】:

            【解决方案5】:

            如果你正在编写好的 C++,那么你应该有很少的析构函数(事实上我认为“很少有析构函数”是衡量 C++ 代码质量的一个很好的指标)。

            我能想到的几个例外是:

            a) 当您处理不会自毁的事物时,例如。 “文件*”。

            b) 当您使用“pimpl”习语时(谷歌搜索“pimpl idiom”)。

            注意。像 std::auto_ptr 和 std::vector 这样的类将属于 (a) 类,因为在某些时候它们需要一个 C 风格的指向内存的指针。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-01-06
              • 1970-01-01
              • 2021-10-09
              • 2010-11-16
              • 2013-05-22
              • 2014-02-02
              • 1970-01-01
              相关资源
              最近更新 更多