2025年4月26日 星期六 乙巳(蛇)年 正月廿七 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

C++析构函数详解

时间:01-10来源:作者:点击数:85

在学习链表的时候,我们知道结点是动态生成的,如果在程序结束之前不释放内存,就会造成内存泄漏。虽然我们已经编写了成员函数Destroy来删除所有动态生成的结点,但是如果我们不知道这个链表对象何时不再使用,那么调用Destroy的时机对我们来说就是个麻烦了。如果过早地调用,则后面的程序可能会出错。既然有构造函数能随着对象的创建而自动被调用,那么有没有一种函数能随着对象的消亡而自动被调用呢?有!那就是析构函数(Destructor)

析构函数是一种随着对象消亡而自动被调用的函数,它的主要用途是释放动态申请的资源。它没有返回类型,没有参数,也没有重载。析构函数的函数名也是指定的,是在构造函数名之前加一个“~”符号。

下面我们为程序15.4.2添上析构函数的功能:(程序15.5)

//node.h

  • #include <iostream>
  • using namespace std;
  • class Node//定义一个链表结点类
  • {
  • public:
  • Node();//构造函数的声明
  • Node(Node &n);//结点拷贝构造函数
  • Node(int i,char c='0');//构造函数重载1
  • Node(int i,char c,Node *p,Node *n);//构造函数重载2
  • ~Node();//结点析构函数
  • int readi() const;//读取idata
  • char readc() const;//读取cdata
  • Node * readp() const;//读取上一个结点的位置
  • Node * readn() const;//读取下一个结点的位置
  • bool set(int i);//重载,通过该函数修改idata
  • bool set(char c);//重载,通过该函数修改cdata
  • bool setp(Node *p);//通过该函数设置前驱结点
  • bool setn(Node *n);//通过该函数设置后继结点
  • private:
  • int idata;//存储数据保密
  • char cdata;//存储数据保密
  • Node *prior;//前驱结点的存储位置保密
  • Node *next;//后继结点的存储位置保密
  • };
  • //未定义的函数与程序15.4.1相同
  • Node::~Node()
  • {
  • cout <<"Node destructor is running..." <<endl;
  • }

//linklist.h

  • #include "node.h"//需要使用链表结点类
  • #include <iostream>
  • using namespace std;
  • class Linklist
  • {
  • public:
  • Linklist(int i,char c);//链表类构造函数
  • Linklist(Linklist &l);//链表深拷贝构造函数
  • ~Linklist();//链表析构函数
  • bool Locate(int i);//根据整数查找结点
  • bool Locate(char c);//根据字符查找结点
  • bool Insert(int i=0,char c='0');//在当前结点之后插入结点
  • bool Delete();//删除当前结点
  • void Show();//显示链表所有数据
  • void Destroy();//清除整个链表
  • private:
  • Node head;//头结点
  • Node * pcurrent;//当前结点指针
  • };
  • //未定义的函数与程序15.4.2相同
  • Linklist::~Linklist()
  • {
  • cout<<"Linklist destructor is running..."<<endl;
  • Destroy();//一个成员函数调用另一个成员函数不需要带上对象名
  • }

//main.cpp 同程序15.4.2

运行结果:
          请输入一个整数和一个字符:
          4 G
          Node constructor is running...
          Linklist constructor is running...
          Node constructor is running...
          Node constructor is running...
          Node constructor is running...
          After Insert
          4 G
          3 F
          2 B 
          1 C
          Node destructor is running...
          After Delete
          4 G
          3 F
          1 C
          Linklist Deep cloner running...
          Node constructor is running...
          Node constructor is running...
          This is Linklist b
          4 G
          3 F
          1 C
          Node destructor is running...
          Node destructor is running...
          After Destroy
          4 G
          This is Linklist b
          4 G
          3 F
          1 C
          Linklist destructor is running...
          Node destructor is running...
          Node destructor is running...
          Node destructor is running...
          Linklist destructor is running...
          Node destructor is running...

在After Destroy之前的两条Node destructor运行是因为调用了a.Destroy(),最后的6条destructor是因为程序运行结束使得对象自动消亡。可见析构函数是在使用delete语句删除动态生成的对象或程序结束对象消亡时自动被调用的。

从最后的2条destructor输出我们发现,当一个对象的成员数据还是对象时,析构函数的运行顺序恰好与构造函数的运行顺序相反:一个大对象先调用析构函数,瓦解成若干成员数据,然后各个成员数据再调用各自的析构函数。这体现出构造函数与析构函数的对称性。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
上一篇:链表类 下一篇:C++拷贝构造函数
推荐内容
相关内容
栏目更新
栏目热门