我目前正在尝试了解类和构造函数/析构函数。我了解两者的作用,但我在使用析构函数时遇到了困难,因为我想不出一个实际的应用程序来使用它。
任何人都可以提供一个解释的例子吗?
我目前正在尝试了解类和构造函数/析构函数。我了解两者的作用,但我在使用析构函数时遇到了困难,因为我想不出一个实际的应用程序来使用它。
任何人都可以提供一个解释的例子吗?
析构函数是特殊的成员函数,用于释放对象分配的任何资源。
最常见的例子是类的构造函数使用new
,而析构函数使用delete
释放内存。
class Myclass
{
int *m_ptr;
public:
Myclass():m_ptr(new int)
{
}
~Myclass()
{
delete m_ptr;
}
//ToDo: Follow Rule of Three
//Provide definitions for copy constructor & copy assignment operator as well
};
析构函数可能是 c++ 最重要的方面,它为您管理资源并允许您添加代码来处理任何特殊清理,例如句柄释放、从套接字断开连接、DB 等。Bjarne Stroustup 还指出这是一件好事关于析构函数:
也有积极的惊喜。最引人注目的是在与资源管理和错误处理(使用异常)相关的技术中普遍使用析构函数。我知道析构函数是个好主意——毕竟,你必须反转构造函数的作用——但我没有意识到它们对于充分利用 C++ 有多么重要。
原文:http: //msdn.microsoft.com/en-us/magazine/cc500572.aspx
这对于习语RAII(资源获取是初始化)也是必不可少的,并由 Bjarne 在本文中解释: http ://www.artima.com/intv/modern3.html
你可以阅读这个关于析构函数的C++ 常见问题解答,它应该对你有更多帮助。
我认为 Als 代码示例是一个很好的示例,您也可以查看维基百科文章中的代码示例,这也是另一个示例。当对象超出范围或被调用时调用析构函数这一事实delete
非常有用。我使用的是一个计时器对象类来计时某些函数调用需要多长时间:
class myTimer
{
mytimer():startTime( TimeNow() )
{}
~myTimer()
{
printf("time taken :%I64d", TimeNow() - startTime);
}
private:
__int64 startTime;
};
所以在我的代码中我会做这样的事情
myClass::myFunction()
{
myTimer timer; // initiliases time to Now.
someOtherFunc();
} // mytimer object is now out of scope and the destructor is called and prints the time it took
假设您有一个用于文件操作的类,例如ifstream
,您喜欢该文件自动关闭,该类的实例消失。在析构函数中关闭文件句柄。
当您具有动态分配的对象的组合时,这些功能最强大
假设我正在制作linkedList
包含指向linkedListNodes
列表的指针的结构,它将包含指向第一个元素的指针,并且取决于单个或双重最后一个元素。
在析构函数中,我将删除列表中的所有元素,因此列表本身。
如果我不对析构函数进行编码,那么当列表超出范围或调用了 delete 时,分配给这些元素的内存将丢失,并且系统无法回收(最明显的是称为内存泄漏)
在这里扩展@Als 的答案,例如你有一堂课,
class A {
B* ptrB; // B is another class / struct / internal type
A() { ptrB = new B(); }
}
int main() {
A* ptrA = new A();
// Do something with A
delete ptrA; // This does not free ptrA->ptrB
}
为了解决这个问题,在 A 中声明一个析构函数,如下所示,
~A() { delete ptrB; } // This is called every time delete is called on
// an object of A
构造函数和析构函数是 RAII(资源分配即初始化)习语中非常重要的部分。将资源(文件、内存、套接字、其他类对象)的获取与对象的生命周期联系起来是一个非常强大的工具。当一个对象超出范围时,无论是通过正常执行还是由于异常,调用对象析构函数允许类正确清理其资源,而无需使用具有大量额外终结步骤的对象来负担代码。