为什么在C ++中需要析构函数?

时间:2008-12-13 11:05:46

标签: c++

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

5 个答案:

答案 0 :(得分:18)

如果你问为什么C ++类有析构函数,有些类除了释放内存之外还有其他要求。例如,您可能有一个分配了一个需要干净地关闭的套接字连接的对象。

此外,'取消'指针使释放它指向的内存,因为其他指针可能正在引用它。

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

答案 1 :(得分:14)

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

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

答案 2 :(得分:9)

首先,您错误地指出当指针超出范围时释放内存。如果原始指针为false,则内存将丢失,并且指向对象持有的任何资源都会丢失。

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

虽然随着C#或Java内存的托管语言被垃圾收集器自动释放,但只有内存才能被释放,并且用户可以在使用地点手动控制所有其他资源。

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

在C ++中,使用RAII习语,每个对象负责它所持有的资源,并且必须在销毁期间释放它们。这意味着如果您在堆栈中使用对象,则会在没有用户交互的情况下释放资源。控制资源的责任在课堂上,用户不能记得手动释放每个资源。

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

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

答案 3 :(得分:0)

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

我能想到的几个例外是:

a)当你处理不破坏自己的事情时,例如。 “FILE *”。

b)当你使用“pimpl”成语时(google为“pimpl idiom”)。

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

答案 4 :(得分:0)

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

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