你如何在c ++中定义解构函数?

时间:2015-09-05 23:56:57

标签: c++ constructor linked-list

刚开始学习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

3 个答案:

答案 0 :(得分:2)

没有。析构函数用于释放/清除对象可能正在使用的任何资源。例如,需要关闭文件句柄,需要将UI资源释放回系统,new编辑的内存需要delete

在您的示例中,计数似乎是int,因此您不需要为此做任何事情,因为该内存是被销毁对象的一部分,但如果您已为此分配内存你的列表你必须在析构函数中释放它。根据您构建列表的方式,您可能希望遍历列表并取消分配每个节点。

答案 1 :(得分:0)

它被称为析构函数而不是解构函数

析构函数代码通常定义了如何结束类实例的生命周期。

通常这将包括内存释放或释放以及资源释放和关闭文件句柄',解锁同步器,它可能还包括更复杂的东西,如中断线程以结束它?生命如果这个线程生命周期在类中...它可能有更多,比如通知已经分配给通知的类的销毁..当你结束一个实例时可能需要很多代码没有析构函数的类,OOP的封装会受到影响

最后请注意,在c ++中,new和delete保留字是使用对象实例的构造函数/析构函数的内存分配器

我希望它足够清楚

答案 2 :(得分:0)

为了消除一个误解,每当一个对象超出范围时就会调用析构函数(一个局部变量命中它创建它的代码块的末尾)。如果一个对象是在全局范围内创建的(在函数之外),它将在程序退出时被销毁。把它想象成整个计划的一大支撑。

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他们。如果您锁定了互斥锁,请将其解锁。如果您正在管理线程,您可能希望通知线程并等待它们完成之前完成。但是这样做会超时,所以你不要挂在一个卡住的线程上。

虽然我们关注这个话题,但请阅读:What is The Rule of Three?

简单地说,如果你有一个析构函数,一个复制构造函数或一个赋值运算符(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时它不会删除列表的任何副本的数据。