刚刚开始学习c++,我对如何编写解构器感到困惑。到目前为止,我知道只要对象被销毁,就会调用解构器,我的理解是当程序结束,c++自动销毁所有对象时。这是否意味着我应该将所有变量重新初始化为它们最初的样子?
我应该这样写吗?
/*In the Header file*/
List();
~List();
//Other function prototypes go here
/*In the Implementation file*/
List::List()
{
head = NULL;
tail = NULL;
count = 1;
}
List::~List
{
head = NULL;
tail = NULL;
count = 1;
}
//Other function bodies go here
No。析构函数用于释放/清除对象可能正在使用的任何资源。例如,文件句柄需要关闭,UI资源需要释放回系统,您拥有的new
ed内存需要被delete
ed。
在你的例子中count看起来像一个int
,所以你不需要为它做任何事情,因为它的内存是被销毁的对象的一部分,但是如果你已经为你的列表分配了内存,你将不得不在析构函数中释放它。根据构造列表的方式,您可能希望遍历列表并释放每个节点。
为了澄清一个误解,只要对象超出作用域(局部变量到达创建它的代码块的末尾),就调用析构函数。如果对象是在全局作用域中(在函数之外)创建的,那么它将在程序退出时被销毁。
void function(object a)
{
object b;
int x = 0;
while (x < 10)
{
object c;
// La la la Doing stuff.
} // c destroyed here. It will be created and destroyed for each run through the loop
a = b;
} //b destroyed here
// a also destroyed here, so watch out passing things into functions if you want them
// back changed.
或使用delete
命令手动销毁
object * d = new object();
// la la la doing stuff
delete d;
由于d
是手动创建的,因此必须手动销毁它。c#和Java的人注意了。
把东西收起来。不要浪费时间将值设置回默认值。他们活不了多久,不会欣赏你的姿态。但是,如果您打开了一个文件,并且它仍然处于打开状态,请关闭它。如果你new
其他对象,delete
他们。如果您锁定了互斥锁,请将其解锁。如果您正在管理线程,您可能希望通知线程并等待它们在完成之前完成。但是要有一个超时时间,这样你就不会挂在卡住的线程上。
既然我们在讨论这个话题,请读一读:什么是"三的法则"?
三规则意味着,如果你有析构函数、复制构造函数或赋值操作符(operator=
),你几乎肯定需要这三者。很多时候,你会看到人们出现奇怪的记忆错误,因为他们没有遵守"三法则"。不要成为那样的人。当你记不住《三法则》的时候,就去找《五法则》。
这如何适用于OP:
List::~List
{
head = NULL; //very probably need to delete this pointer
tail = NULL; //and possibly this one
count = 1; // don't need this at all
}
所以它应该看起来像:
List::~List
{
if (head != NULL)
{
delete head; // This should start a chain reaction deleting all of the linked
// items in the list, ensuring that they have all been freed
}
}
此外,OP应该具有复制构造函数和赋值操作符,以确保在删除List时不会同时删除列表的任何副本的数据。
叫做析构函数而不是解构函数
析构函数代码通常定义如何结束类实例的生命周期。
通常这将包括内存释放或释放以及资源释放'关闭文件句柄',解锁同步器,它也可能包括更复杂的东西,如中断线程结束它的生命,如果这个线程的生命周期是在类内。它可能不止于此,比如将类的销毁通知给指定通知的人。当你结束一个没有析构函数的类的实例时,可能需要大量的代码,OOP的封装将会受到影响
c++中的最后一点:new、delete保留字是使用对象实例的构造函数/析构函数的内存分配器
我希望这足够清楚