C++析构函数详解
析构函数(Destructor)也是一种特殊的成员函数,没有返回值,不需要程序员显式调用(程序员也没法显式调用),而是在销毁对象时自动执行。构造函数的名字和类名相同,而析构函数的名字是在类名前面加一个
~符号。注意:析构函数没有参数,不能被重载,因此一个类只能有一个析构函数。如果用户没有定义,编译器会自动生成一个默认的析构函数。
上节我们定义了一个 VLA 类来模拟变长数组,它使用一个构造函数为数组分配内存,这些内存在数组被销毁后不会自动释放,所以非常有必要再添加一个析构函数,专门用来释放已经分配的内存。请看下面的完整示例:
运行结果:#include <iostream>
using namespace std;
class VLA{
public:
VLA(int len); //构造函数
~VLA(); //析构函数
public:
void input(); //从控制台输入数组元素
void show(); //显示数组元素
private:
int *at(int i); //获取第i个元素的指针
private:
const int m_len; //数组长度
int *m_arr; //数组指针
int *m_p; //指向数组第i个元素的指针
};
VLA::VLA(int len): m_len(len){ //使用初始化列表来给 m_len 赋值
if(len > 0){ m_arr = new int[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)<<endl; }
else{ cout<<*at(i)<<", "; }
}
}
int * VLA::at(int i){
if(!m_arr || i<0 || i>=m_len){ return NULL; }
else{ return m_arr + i; }
}
int main(){
//创建一个有n个元素的数组(对象)
int n;
cout<<"Input array length: ";
cin>>n;
VLA *parr = new VLA(n);
//输入数组元素
cout<<"Input "<<n<<" numbers: ";
parr -> input();
//输出数组元素
cout<<"Elements: ";
parr -> show();
//删除数组(对象)
delete parr;
return 0;
}
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。
析构函数的执行时机
析构函数在对象被销毁时调用,而对象的销毁时机与它所在的内存区域有关。不了解内存分区的读者请阅读《C语言内存精讲》专题。在所有函数之外创建的对象是全局对象,它和全局变量类似,位于内存分区中的全局数据区,程序在结束执行时会调用这些对象的析构函数。
在函数内部创建的对象是局部对象,它和局部变量类似,位于栈区,函数执行结束时会调用这些对象的析构函数。
new 创建的对象位于堆区,通过 delete 删除时才会调用析构函数;如果没有 delete,析构函数就不会被执行。
下面的例子演示了析构函数的执行。
运行结果:#include <iostream>
#include <string>
using namespace std;
class Demo{
public:
Demo(string s);
~Demo();
private:
string m_s;
};
Demo::Demo(string s): m_s(s){ }
Demo::~Demo(){ cout<<m_s<<endl; }
void func(){
//局部对象
Demo obj1("1");
}
//全局对象
Demo obj2("2");
int main(){
//局部对象
Demo obj3("3");
//new创建的对象
Demo *pobj4 = new Demo("4");
func();
cout<<"main"<<endl;
return 0;
}
1
main
3
2
- 随机文章
- 东航马尔代夫计划(东航跨越海洋,计划开通马尔代夫航线)
- 中国 马尔代夫 足彩(中马足彩,你选谁?)
- 马尔代夫风格音乐(畅游印度洋,感受马尔代夫风情音乐)
- 北戴河和马尔代夫(北戴河与马尔代夫:海岛度假胜地对比)
- 信阳马尔代夫头条(信阳拥有的亚洲最大水秀表演即将上演)
- 孟津 马尔代夫(旅游胜地:孟津马尔代夫)
- 乙肝 马尔代夫(马尔代夫:乙肝预防与控制指南)
- 岷县景区马尔代夫(岷县打造马尔代夫,打造美丽水上乐园)
- 广东马尔代夫滑梯(广东别样风情:马尔代夫滑梯独家亮相)
- 广东马尔代夫海岛(广东最美马尔代夫海岛,等你来发现!)
- 带鱼竿去马尔代夫(带鱼竿玩转马尔代夫,全新海钓体验!)
- 大学马尔代夫校园(重返蓝色海洋:大学马尔代夫校园揭幕)
- 沈阳奥体马尔代夫(沈阳奥体马尔代夫游,享受海岛慢生活)
- 江苏徐州马尔代夫(徐州建设“远东马尔代夫”旅游目的地)
- 胶南马尔代夫会馆(胶南市政府为爱国华侨建马尔代夫会馆)
- 芜湖马尔代夫事件(芜湖旅行社误导游客赴马尔代夫遭拘留)
- 深度介绍马尔代夫(探索马尔代夫:天堂之岛的美丽和魅力)
- 徐州马尔代夫在哪(徐州哪里有类似马尔代夫的度假胜地?)
- 退钱 马尔代夫(马尔代夫旅游行程退款:如何申请?)
- 沈阳马尔代夫酒店(沈阳马尔代夫酒店:享受梦幻海岛风光)
- 连云港到马尔代夫(从连云港起航,探索美丽的马尔代夫!)
- 足球马尔代夫别称(马尔代夫:一个令人兴奋的足球旅行地)
- 旅行套餐马尔代夫(马尔代夫旅行套餐,享受海岛度假之旅)
- 马尔代夫上空俯瞰(马尔代夫美景:游客在飞机上俯瞰上空)
- 马尔代夫中国雇员(马尔代夫新增中国员工,促进中马友谊)
- 马尔代夫为何有钱(马尔代夫奢华背后的财源到底是什么?)
- 马尔代夫仙女姐姐(马尔代夫女子成了站着划浆的绝技高手)
- 马尔代夫书籍大全(马尔代夫必读书单,旅途中的最佳伴侣)
- 马尔代夫专用插座(马尔代夫旅行必备:专用插座使用指南)
- 斯航 马尔代夫(新标题:斯堪航空公司恢复飞往马尔代夫航班)
