• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 详解C++编程中的析构函数

详解C++编程中的析构函数

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++析构函数,c++中析构函数,c++析构函数的用法,c++析构函数怎么写,析构函数等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

C++析构函数

创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作(例如回收创建对象时消耗的各种资源),这个函数被称为析构函数。

析构函数(Destructor)也是一种特殊的成员函数,没有返回值,不需要用户调用,而是在销毁对象时自动执行。与构造函数不同的是,析构函数的名字是在类名前面加一个”~“符号。

注意:析构函数没有参数,不能被重载,因此一个类只能有一个析构函数。如果用户没有定义,那么编译器会自动生成。

析构函数举例:

#include <iostream>
using namespace std;
class Student{
private:
  char *name;
  int age;
  float score;
public:
  //构造函数
  Student(char *, int, float);
  //析构函数
  ~Student();
  //普通成员函数
  void say();
};
Student::Student(char *name1, int age1, float score1):name(name1), age(age1), score(score1){}
Student::~Student(){
  cout<<name<<"再见"<<endl;
}
void Student::say(){
  cout<<name<<"的年龄是 "<<age<<",成绩是 "<<score<<endl;
}
int main(){
  Student stu1("小明", 15, 90.5f);
  stu1.say();
  
  Student stu2("李磊", 16, 95);
  stu2.say();
  
  Student stu3("王爽", 16, 80.5f);
  stu3.say();
  cout<<"main 函数即将运行结束"<<endl;
  
  return 0;
}
</div>

运行结果:

小明的年龄是 15,成绩是 90.5
李磊的年龄是 16,成绩是 95
王爽的年龄是 16,成绩是 80.5
main 函数即将运行结束
王爽再见
李磊再见
小明再见
</div>

可以看出,析构函数在 main 函数运行结束前被执行,并且调用顺序和构造函数正好相反,为了方便记忆,我们可以将之理解为一个栈,先入后出。
析构函数的执行顺序为什么是反的。
析构函数在对象被销毁前执行;要知道析构函数什么时候被调用,就要先知道对象什么时候被销毁。

对象可以认为是通过类这种数据类型定义的变量,它的很多特性和普通变量是一样的,例如作用域、生命周期等。由此可以推断,对象这种变量的销毁时机和普通变量是一样的。

总结起来,有下面几种情况:
1) 如果在一个函数中定义了一个对象(auto 局部变量),当这个函数运行结束时,对象就会被销毁,在对象被销毁前自动执行析构函数。

2) static 局部对象在函数调用结束时并不销毁,因此也不调用析构函数,只有在程序结束时(如 main 函数结束或调用 exit 函数)才调用 static 局部对象的析构函数。

3) 如果定义了一个全局对象,也只有在程序结束时才会调用该全局对象的析构函数。

4) 如果用 new 运算符动态地建立了一个对象,当用 delete 运算符释放该对象时,先调用该对象的析构函数。

注意:析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作,使这部分内存可以分配给新对象使用。

C++调用构造函数和析构函数的顺序
在使用构造函数和析构函数时,需要特别注意对它们的调用时间和调用顺序。在一般情况下,调用析构函数的次序正好与调用构造函数的次序相反:最先被调用的构造函数,其对应的(同一对象中的)析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。如例9.5所示,先执行stud2的析构函数,再执行stu1的析构函数。

可以简记为:先构造的后析构,后构造的先析构,它相当于一个栈,先进后出。

但是,并不是在任何情况下都是按这一原则处理的。对象可以在不同的作用域中定义,可以有不同的存储类别。这些会影响调用构造函数和析构函数的时机。

下面归纳一下什么时候调用构造函数和析构函数:
1) 在全局范围中定义的对象(即在所有函数之外定义的对象),它的构造函数在文件中的所有函数(包括main函数)执行之前调用。但如果一个程序中有多个文件,而不同的文件中都定义了全局对象,则这些对象的构造函数的执行顺序是不确定的。当main函数执行完毕或调用exit函数时(此时程序终止),调用析构函数。

2) 如果定义的是局部自动对象(例如在函数中定义对象),则在建立对象时调用其构造函数。如果函数被多次调用,则在每次建立对象时都要调用构造函数。在函数调用结束、对象释放时先调用析构函数。

3) 如果在函数中定义静态(static )局部对象,则只在程序第一次调用此函数建立对象时调用构造函数一次,在调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用析构函数。

例如,在一个函数中定义了两个对象:

void fn(){
  Student stud1; //定义自动局部对象
  static Student stud2; //定义静态局部对象
}
</div>


在调用fn函数时,先调用stud1的构造函数,再调用stud2的构造函数,在fn调用结束时,stud1是要释放的(因为它是自动局部对象),因此调用stud1的析构函数。而stud2 是静态局部对象,在fn调用结束时并不释放,因此不调用stud2的析构函数。直到程序结束释放stud2时,才调用stud2的析构函数。可以看到stud2是后调用构造函数的,但并不先调用其析构函数。原因是两个对象的存储类别不同、生命周期不同。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++构造函数和析构函数的调用顺序
  • C++中构造函数与析构函数的调用顺序详解
  • C++中的friend函数详细解析
  • 简单解读C++中的虚函数
  • 详解C++中如何将构造函数或析构函数的访问权限定为private
  • 浅谈C++基类的析构函数为虚函数
  • 简单介绍C++编程中派生类的析构函数
  • 详解C++编程中的析构函数
  • C++中函数的用法小结
  • C++类成员构造函数和析构函数顺序示例详细讲解

相关文章

  • 2017-05-28VC++简单实现关机、重启计算机实例代码
  • 2017-05-28Recommended C Style and Coding Standards中文翻译版第1/3页
  • 2017-05-28C语言中字符串常用函数strcat与strcpy的用法介绍
  • 2017-05-28C++中队列的建立与操作详细解析
  • 2017-05-28深入讲解C++数据类型转换的相关函数的知识
  • 2017-05-28实例解析C++设计模式编程中简单工厂模式的采用
  • 2017-05-28C语言实现类似wget的进度条效果
  • 2017-05-28C++中输出十六进制形式的字符串
  • 2017-05-28C语言与JAVA的区别是什么(推荐)
  • 2017-05-28C++插入排序算法实例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++中虚函数与纯虚函数的用法
    • C++线程池的简单实现方法
    • 深入C++浮点数无效值定义与判定的解决办法
    • C语言中的文件是什么?
    • 快速解决boost库链接出错的问题(分享)
    • C++基础之this指针与另一种“多态”
    • GCC 编译使用动态链接库和静态链接库的方法
    • 结合C++11新特性来学习C++中lambda表达式的用法
    • c++将引用或者是指针作为函数参数实现实参的运算
    • 解析shell排序的实现代码

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有