析构函数:
创建对象时系统会自动调用析构函数进行初始化工作,同样销毁对象时系统也会自动调用一个函数来进行清理工作
定义:
与构造函数一样,也是一个特俗的成员函数,没有返回值,不需要程序员显示调用(程序员也没法显示调用),而是在销毁对象时自动执行。构造函数的名字和类名相同,析构函数的名字是在类名前面加一个~符号
析构函数不能重载,一个类只能有一个析构函数,如果用户没有定义,编译器会自动生成一个默认的析构函数
#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){
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;
VAL *parr=new VAL(n);
//输入数组元素
cout<<"Input"<<n<< "Number:";
parr->input();
//输出数组元素
parr->show();
//删除数组(对象)
delete parr;
return 0;
}
~VLA()就是VLA析构函数,她的唯一作用就是在删除对象(delete parr)后释放已经分配的内存
对象过期时自动调用的特殊成员函数
析构函数一般用来完成清理工作
析构函数的名称是在类名前加上~
析构函数没有参数,只能有一个
注意:
析构函数用来释放对象使用的资源,并销毁对象的非static数据成员
无论何时一个对象被销毁,都会自动调用其析构函数(隐式析构)
释放是栈内存中的对象 用析构函数就可以
但是当对象是堆内存中时,使用完毕时,记得delete ,释放内存。
第一种实例化方式
栈在内存中创建:类似于声明变量
自定义类型名 对象名[([参数列表])];
Student stu(); Student stu;
注意:
1 stu对象由系统创建并释放,不用担心出现内存泄漏
2 声明周期只在声明区域的大括号内
栈内存的优势是存取速度比较快(仅次于寄存器),缺点是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性
第二中实例化方式:
在堆内存中创建:需要new关键字
Student* p_stu1=new Student();
Student* p_stu2=newStudent;
auto* p_stu3=new Student();
注意:
p_stu1是指针,必须使用delete释放
使用灵活(可以赋值给全局变量,可以把对象作为函数的返回值返回)
用好了功能强大,用不好很危险
析构函数的执行机制:
析构函数在对象被销毁时调用,而对象的销毁时机与它所在的内存区域有关。
在所有函数之外创建的对象叫做全局对象,与全局变量类似,位于内存分区中的全局数据区,程序会在结束执行时会调用这些对象的析构函数
在函数·内部创建的对象时局部对象,他和全局变量类似,位于栈区,函数执行结束时会调用这些对象的析构函数
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(){
//局部变量
Dmeo obj1("1");
}
//全局变量
Dmeo obj2("2");
int main(){
//局部变量
Demo obj3("3");
//new创建的对象
Demo *pobj4=new Demo("4");
func();
delete pobj4;
return 0;
}