-
2021-01-17 17:48:57
析构函数也是一个在类中跟构造函数类似的特殊功能的成员函数,作用与构造函数相反,是在对象的声明周期结束的时候会被自动调用.在C++中析构函数的名字跟类名相同,并在前面带上一个取反的符号~,表达的意思也跟构造函数的过程相反.
默认情况下,如果类没有定义自己的析构函数,编译器会自动为该类生成一个默认的析构函数,只不过函数体是空的,也就是什么都没做.所有,如果需要在对象被删除的时候做一些操作的话,就得自己定义析构函数.
以下几种情况会自动调用析构函数:
①如果一个函数中定义了一个局部变量的对象,那么当这个函数执行结束时也就是该变量对象生命周期结束的时候,所以析构函数会被自动调用.
②全局变量或者static类型的变量,他们的生命周期一般是在程序退出的时候,该对象的析构函数才会被调用.
③如果是用new操作符动态的创建了一个对象,只有当用delete进行释放该对象的时候,析构函数才会被调用.
析构函数的作用:
那构造函数来说,构造函数是新建对象吗?不是,而是在对象被创建出来后自动被调用的,用来初始化相关信息的函数.同理:析构函数也不是用来删除对象的,而是当对象被删除的时候自动被调用的,用来做一些对象被删除之前的清理工作,只有对象的生命周期结束,那么程序就自动执行析构函数来完成这个工作.
析构函数的特点:
析构函数不返回任何值,没有函数类型,也没有任何函数的参数.析构函数不能被重载,所以,一个类中可以有多个构造函数,但只有一个析构函数.
析构函数使用示例:CStudent::~CStudnet() { cout<<"~CStudent() callec."<<endl; }
//本文来源于VC驿站,仅作为个人学习记录
更多相关内容 -
C++析构函数定义和使用
2021-06-10 20:22:40析构函数(destructor)是一个特殊的成员函数,它的作用与构造函数相反,它的名字是类名的前面加一个“~”符号。在C++中“~”是位“取反”运算符,从这一点可以想到:析构函数是与构造函数作用相反的函数。例如:...析构函数
2.1 析构函数定义和使用
析构函数(destructor)是一个特殊的成员函数,它的作用与构造函数相反,它的名字是类名的前面加一个“~”符号。在C++中“~”是位“取反”运算符,从这一点可以想到:析构函数是与构造函数作用相反的函数。例如:
class student{
public:
student()//构造函数
{
}
~student() //析构函数
{ }
void print(){}
};
可以看到,定义了一个student类。然后,定义student类的构造函数和析构函数。其中,析构函数的定义如下:
~student(){ }
那么,函数名是类名前面添加取反符号“~”,而且,函数没有参数。
当对象的生命周期结束的时候,就会自动执行析构函数。如果出现以下几种情况,程序就会执行析构函数:
(1) 如果在一个函数中定义了一个对象,那么,该对象就是局部对象,当这个函数被调用结束时,对象的生命周期结束。此时,对象应该释放(销毁),在对象释放(销毁)前自动执行析构函数。
(2) static 局部对象在函数调用结束时对象并不释放(销毁),因此,不调用析构函数,只在main() 函数结束或调用exit()函数结束程序的时候,才调用static局部对象的析构函数。
因为static局部对象的生命周期是整个程序运行过程,所以,只有程序结束运行的时候,static局部对象的生命周期才结束,才执行类的析构函数。
(3) 如果定义了一个全局对象,全局对象的生命周期是整个程序运行过程,所以,当程序结束运行的时候,全局对象才销毁,此时,调用该全局对象的析构函数。
(4) 如果用new运算符动态地建立了一个对象,当用delete运算符释放该对象时,先调用该对象的析构函数。
析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前,完成一些清理工作。使这部分内存可以被程序分配给新对象使用。程序设计者要设计好析构函数,以完成所需的功能,只要对象的生命周期结束,程序就会自动执行析构函数来完成这些工作。
析构函数不返回任何数值,也没有函数类型 和 函数参数。由于没有函数参数,因此,它不能被重载。一个类可以有多个构造函数,但是,只能有一个析构函数。
一般情况下,类的设计者应当在声明类的同时定义析构函数,以指定如何完成“清理”的工作。如果用户没有定义析构函数,C++编译系统会自动生成一个 默认析构函数,但是,它只是有析构函数的名称和形式,实际上什么操作都不进行。想让析构函数完成任何工作,都必须在定义的析构函数中执行。
如下是一个程序测试例子,讲解构造函数和析构函数的使用。
程序运行结果如下:
在main()函数中,定义一个if(1){}代码块,在代码块中定义stud局部变量。当退出代
码块的时候,销毁stud局部变量,看到析构函数的调用。
所以,我们看到对象销毁的时候,自动调用析构函数。析构函数是不可以手动调用的。是对象销毁的时候,由系统自动调用。
所以,对象销毁的时候,我们想释放一些资源,就可以放在析构函数中操作。例如,student类中的name, addr是动态申请的内存。那么,在析构函数中就释放这些内存。
韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip
-
构造函数与析构函数
2016-02-16 14:46:56如果用户没有显式地提供析构函数,系统会提供一个默认的析构函数。析构函数也是以类名作为函数名,与构造函数不同的是在函数名前添加一个“~”符号,标识该函数是析构函数。析构函数没有返回值,甚至void类型也不... -
析构函数的定义
2017-11-02 15:24:21首先来到一个问题,什么是析构函数,在《C++语言程序设计》(清华大学出版社,以后的博客关于C++的概念部分大多借鉴于此版教材)中,析构函数与构造函数对应,构造函数是始,析构函数是终,比如借了邻居的东西(内存...首先来到一个问题,什么是析构函数,在《C++语言程序设计》(清华大学出版社,以后的博客关于C++的概念部分大多借鉴于此版教材)中,析构函数与构造函数对应,构造函数是始,析构函数是终,比如借了邻居的东西(内存),是要还的(释放),析构函数是做收尾工作的。
他与构造函数的作用几乎正好相反,用来完成对象呗删除前的一些清理工作,是在对象的生存期即将结束的时刻被自动调用的(有特殊情况是可以主动调用析构函数的,后面的博客会讲到),析构函数调用完,也就是说对象彻底凉了,对象用掉的内存空间也要给人家释放回来。一般是个公有函数成员,命名方式是:~类名(){}
和构造函数不同的是析构函数不接受任何的参数,也就是说上述命名方式中,小括号里面不可以有任何东西。如果希望程序在对象被删除之前的时刻自动完成某些事(比如说delete掉new出来的内存),就可以把你想完成的事件写进析构函数中。此外,析构函数的调用执行顺序与构造函数刚好相反,这也是显而易见的。
class Clock{
public:
Clock(); ---------->构造函数
void setTime(int newh,int newm,int news);--------->属性
void showTime();------------->行为
~Clock(){}---------------->析构
private:
int hour,mintue,second; --------------->私有成员属性
};
创建组合类,类有内嵌对象中,构造函数和析构函数都将按照一定顺序来多次调用。
构造:
调用顺序按照内嵌对象在组合类的定义中出现的顺序,注意,内嵌对象在构造函数的初始化列表中出现的顺序与内嵌对象构造函数的调用顺序没有关系。然后再执行自己类的构造函数。
析构函数相反,析构函数被执行完毕后,内嵌对象的析构函数被一一执行,这些内嵌函数的析构函数调用顺序与他们在组合类的定义中出现的次序是反过来的。这种时候要调用内嵌对象的析构函数,所以此时没有函数体的析构函数也并不是什么都不做。
-
浅析:类只能有一个析构函数
2015-04-01 12:42:11类的构造函数与析构函数都是与类同名(析构函数需要加上'~'),没有返回值的;...但是由于析构函数是没有参数的,那么从而无法通过参数的不同来达到重载多个析构函数的目的,从而析构函数只能有一个。 析构函数是由系类的构造函数与析构函数都是与类同名(析构函数需要加上'~'),没有返回值的;而构造函数是可以有参数的,但是析构函数是不能有参数的。
我们知道类可以有多个构造函数,这些构造函数是重载函数的关系,也就是说函数名都是相同的,区别它们主要靠参数的不同(参数个数和参数类型)。
但是由于析构函数是没有参数的,那么从而无法通过参数的不同来达到重载多个析构函数的目的,从而析构函数只能有一个。
析构函数是由系统负责调用的,也可以手工显示调用,但是显示调用析构函数是不会析构该对象的,也就是说显示调用析构函数和没有显示调用析构函数是一样的,
#include<iostream>
using namespace std;
class A
{
public:
A(){};
void fun() {cout<<"The object exists!";};
~A(){};int bbb;
};
int main()
{
A *a=new A();a->bbb=345;
a->~A();//显示调用析构函数后,对象a还存在吗?
a->fun();
//编译运行后a->fun()能够输出,对象a仍存在
return 0;
}
再来看看汇编代码
在VC的DEBUG模式下,通过查看反汇编代码,可以看到,直接调用析构函数的语句没有任何汇编代码对应它,就和没有这一语句一模一样.由此看来,析构函数是自动调用的,如果显示调用是不会析构对象的。
……
14: a->bbb = 345;
0040105B mov ecx,dword ptr [ebp-4]
0040105E mov dword ptr [ecx],159h
15: a->~A();
16: a->fun();
00401064 mov ecx,dword ptr [ebp-4]
00401067 call @ILT+15(A::fun) (00401014)
……
由以上可知,一个类只能有一个析构函数,析构函数没有返回值没有参数,只能由系统调用时才析构对象。
-
C++中析构函数为虚函数
2019-04-12 23:13:17(1)析构函数定义为虚函数时:基类指针可以指向派生类的对象(多态性),如果删除该指针delete []p;就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全... -
C++类的理解(二):函数重载和多个构造函数,以及析构函数
2018-08-14 08:54:35这个函数接受两个整型变量,返回他们的和,但如果我还要一些功能,比如两个double类型的和,一个整型和100的和,并且我也想用add这个函数名怎么办? 函数重载的概念就是用来解决这个问题的,我们... -
为什么析构函数必须是虚函数?为什么默认的析构函数不是虚函数?
2020-03-26 07:52:04微信搜索“编程笔记本”,获取更多信息 ------------- codingbook2020 ------------- 今天我们来谈一谈面试 C++ ...在某基类中声明为 virtual并在一个或多个派生类中被重新定义的成员函数,用法格式为:virtual... -
C++类的默认成员函数——构造函数&析构函数
2018-07-07 21:39:37当成员变量是私有的时候,要对它们初始化就必须用一个公有的成员函数来进行。同时这个成员函数应在仅且在对象定义时自动的执行一次,这个函数我们就叫做构造函数。2. 构造函数的特点(1)函数名与类名相同;(2)无... -
深入探索C++对象模型(九) 析构函数 (以及显式定义的析构函数问题、析构函数Rules of Three)
2018-06-03 17:30:40如果类没有定义析构函数,那么只有类中含有成员对象(或者本类的基类)拥有析构函数的情况下,编译器才会合成一个出来,否则析构函数被视为不要,也就不需要合成。例如,如下类,虽然Point类拥有虚函数:[cpp] view... -
【C++要笑着学】类的默认成员函数详解 | 构造函数 | 析构函数 | 构造拷贝函数
2022-03-08 18:02:17我是柠檬叶子C,本章将继续讲解C++中的面向对象的知识点,本篇主要讲解默认成员函数中的构造函数、析构函数和拷贝构造函数。还是和以前一样,我们将由浅入深地去讲解,以 "初学者" 的角度去探索式地学习。会一步步地... -
C++析构函数
2019-09-23 08:45:21C++析构函数 一、认识析构函数 析构函数也是一种特殊... 一个类只能有且有一个析构函数,如果没有显式的定义,系统会生成一个缺省的析构函数(合成析构函数)。 因为无参数无返回值析构函数不能重载。每有一次构... -
定义一个Complex类,为其定义构造函数,析构函数,
2019-04-23 17:17:04定义一个Complex类,为其定义构造函数,析构函数,试对下列几个运算符进行重载:++,=,!=,+,-,==,其中要求要有成员重载形式和友元重载形式,而且,++运算符要求实现先加和后加两种形式。 #include<... -
析构函数可以是纯虚的么
2019-05-12 19:59:38C++中析构函数可以为纯虚函数吗? 众所周知,在实现多态的过程中,一般将基类的析构函数设为virtual,以便在delete的时候能够多态的链式调用。那么析构函数是否可以设为纯虚呢? class CBase { public: CBase() ... -
类内、外定义&构造函数&析构函数
2017-02-12 18:57:571.类内定义与内联函数 内联函数: (1)类内定义时,定义的函数会默认为内联函数(inline);...要求:定义一个teacher类,要求分别采用同文件类外定义和分文件类外定义的方式完成,数据成员有: -
C++:基类析构函数为什么要定义为虚函数
2019-07-19 15:51:39在C++实现多态里,有一个关于 析构函数的重写问题:基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。这里他们的函数名不相同,看起来违背了重写的规则,但实际上编译器对析构函数的名称... -
析构函数的作用及合成析构函数
2020-01-29 19:59:30如果类需要析构函数,那么也需要复制操作符和复制构造函数。 何时调用析构函数? 当对象的引用或指针超出作用域时,不会运行析构函数,只有删除指向动态分配对象的指针或实际对象(而不是对象的引用)超出作用... -
C++ Qt中 类的构造函数 & 析构函数
2020-10-26 14:12:36类的构造函数是一个特殊的成员函数,它会在每次创建类的新对象时执行。 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。 #include <iostream> using namespace std; ... -
c++之抽象类的纯虚析构函数
2020-01-06 10:51:36定义:在定义一个表达抽象概念的基类时,有时无法给出某些函数的具体实现方法,就可以将这些函数声明为纯虚函数。 2.抽象类 定义:声明了纯虚函数的类,都成为抽象类。 主要特点:抽象类只能作为基类来派生新类,不... -
C++:什么情况下需要将析构函数定义为虚函数?
2016-10-17 15:55:22C++:什么情况下需要将析构函数定义为虚函数。 -
C++析构函数何时需要自定义?
2020-06-02 16:12:27析构函数:如果我们自己不写,编译器会帮我们写(编译器自己写的析构里面什么都不干)。什么时候必须要我们自己写?如果本类中一个成员变量是别的对象的指针,而且这个指针不是传进来的地址而是这个指针指向的对象... -
C#析构函数
2017-01-11 19:04:36一个类只能有一个析构函数。 无法继承或重载析构函数。 无法调用析构函数。它们是被自动调用的。 析构函数既没有修饰符,也没有参数。 例如,下面是类 Car 的析构函数的声明: class Car { -
C/C++基础 -- 析构函数
2020-07-08 13:08:14C/C++基础 -- 析构函数1、析构函数1.1、析构函数的定义1.2、何时调用析构函数1.3、合成析构函数2、何时需要编写析构函数*3、析构函数三法则*4、构造函数和析构函数的调用次序5、实例: 本博文由 西北工业大学MOOC ... -
C++ 析构函数
2016-09-21 00:02:15析构函数如果我们不写的话,C++ 会帮我们自动的合成一个,就是说:C++ 会自动的帮我们写一个析构函数。很多时候,自动生成的析构函数可以很好的工作,但是一些重要的事迹,就必须我们自己去写析构函数。 析构函数... -
浅谈析构函数调用次数
2020-03-15 21:29:52这个时候,我们不需要什么操作,析构函数会自动调用 而当对象位于堆区 例如new出来的对象,调用析构函数是在我们delete它的时候被调用的 class A { int v; static int n; public: A ( int n=0):v(... -
什么时候析构函数需要定义为虚函数
2017-07-12 09:22:361.每个析构函数(不加 virtual) 只负责清除自己的成员。 2.可能有基类指针,指向的确是派生类成员的情况。(这是很正常的), 那么当析构一个指向派生类成员的基类指针时,程序就不知道怎么办了。 所以要保证... -
C#析构函数(方法)
2021-03-18 09:32:48一个类只能有一个析构函数。 无法继承或重载析构函数。 无法调用析构函数。它们是被自动调用的。 析构函数既没有修饰符,也没有参数。 析构方法的定义语法形式如下。 ~方法名() { 语句块; } 在析构方法中不带... -
析构函数为虚函数
2019-06-20 12:37:14多态是面向对象的一个基本属性,包括静态多态(编译阶段)和动态多态(运行阶段),静态多态主要是指函数参数不同产生的多态性,是在编译阶段可以识别的一种多态机制,而运行时多态则主要用于基类指针指向派生类对象...