C++析构函数详解
创始人
2025-05-31 21:56:50
0

创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作,例如释放分配的内存、关闭打开的文件等,这个函数就是析构函数。

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

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

上节我们定义了一个 VLA 类来模拟变长数组,它使用一个构造函数为数组分配内存,这些内存在数组被销毁后不会自动释放,所以非常有必要再添加一个析构函数,专门用来释放已经分配的内存。请看下面的完整示例:

#include
usingnamespace std;class VLA{
public:
VLA(int len);//构造函数
~VLA();//析构函数
public:
voidinput();//从控制台输入数组元素
voidshow();//显示数组元素
private:
int*at(int i);//获取第i个元素的指针
private:
constint m_len;//数组长度
int*m_arr;//数组指针
int*m_p;//指向数组第i个元素的指针
};VLA::VLA(int len):m_len(len){//使用初始化列表来给 m_len 赋值
if(len >0){ m_arr =newint[len];/*分配内存*/}
else{ m_arr = NULL;}
}
VLA::~VLA(){
delete[] m_arr;//释放内存
}
void VLA::input(){
for(int i=0; m_p=at(i); i++){ cin>>*at(i);}
}
void VLA::show(){
for(int i=0; m_p=at(i); i++){
if(i == m_len -1){ cout<<*at(i)<=m_len){return NULL;}
else{return m_arr + i;}
}intmain(){
//创建一个有n个元素的数组(对象)
int n;cout<<"Input array length: ";cin>>n;
VLA *parr =newVLA(n);
//输入数组元素cout<<"Input "<input();
//输出数组元素cout<<"Elements: ";parr ->show();
//删除数组(对象)
delete parr;return0;
}

运行结果:

Input array length: 5

Input 5 numbers: 99 23 45 10 100

Elements: 99, 23, 45, 10, 100

~VLA()就是 VLA 类的析构函数,它的唯一作用就是在删除对象(第 53 行代码)后释放已经分配的内存。

函数名是标识符的一种,原则上标识符的命名中不允许出现~符号,在析构函数的名字中出现的~可以认为是一种特殊情况,目的是为了和构造函数的名字加以对比和区分。

注意:at() 函数只在类的内部使用,所以将它声明为 private 属性;m_len 变量不允许修改,所以用 const 进行了限制,这样就只能使用初始化列表来进行赋值。

C++ 中的 new 和 delete 分别用来分配和释放内存,它们与C语言中 malloc()、free() 最大的一个不同之处在于:用 new 分配内存时会调用构造函数,用 delete 释放内存时会调用析构函数。构造函数和析构函数对于类来说是不可或缺的,所以在C++中我们非常鼓励使用 new 和 delete。

析构函数的执行时机

析构函数在对象被销毁时调用,而对象的销毁时机与它所在的内存区域有关。

在所有函数之外创建的对象是全局对象,它和全局变量类似,位于内存分区中的全局数据区,程序在结束执行时会调用这些对象的析构函数。

在函数内部创建的对象是局部对象,它和局部变量类似,位于栈区,函数执行结束时会调用这些对象的析构函数。

new 创建的对象位于堆区,通过 delete 删除时才会调用析构函数;如果没有 delete,析构函数就不会被执行。

下面的例子演示了析构函数的执行。

#include
#include
usingnamespace std;class Demo{
public:
Demo(string s);
~Demo();
private:
string m_s;
};
Demo::Demo(string s):m_s(s){}
Demo::~Demo(){ cout<

运行结果:

1

main

3

2

相关内容

热门资讯

懵圈了!西亚卡姆捧杯东决MVP... 懵圈了!西亚卡姆捧杯东决MVP竟不知有奖?步行者时隔25年再进总决赛! 导语:篮球场上什么奇事没有?...
没悬念了?金球奖最新赔率:登贝... 北京时间6月2日消息,相关机构更新了2025年金球奖的赔率,巴黎前锋登贝莱领跑。2024-25赛季,...
乌克兰最大胆无人机攻击,预示着... (一) 不得不说,这是迄今乌克兰最大胆也是最成功的一次无人机集群攻击。 看了一下,攻击目标甚至远到俄...
加紧实施更加积极有为的宏观政策 金观平 近期召开的中央政治局会议强调,要加紧实施更加积极有为的宏观政策,用好用足更加积极的财政政策和...
新修订的《快递暂行条例》施行 央视网消息(新闻联播):6月1日起,《国务院关于修改〈快递暂行条例〉的决定》正式施行。此次修改,专门...
here we go!罗马诺:... 直播吧06月01日讯 here we go!罗马诺:凯莱赫总价1800万英镑加盟布伦特福德
美国又一州出手:内布拉斯加州拟... IT之家 6 月 2 日消息,据外媒 The Verge 5 月 31 日报道,美国内布拉斯加州州长...
“法援护苗”专项行动一年来 未... 本报北京5月29日电(记者张璁)记者从司法部获悉:“法援护苗”专项行动开展一年来,各级司法行政机关从...