1.前言
大部分对象在使用之之后没有正确的从内存清理完毕,造成内存泄露也是C++出错的主要领域
引入类的析构是正确的从内存中清量类的对象
一般什么时候触发并调用类的析构函数呢?
答案是:当类实例对象超出它的有效作用域时,也就是撤消类对象时,自动调用析构函数来清理对象
构造函数用来初始化成员,析造函数则是用来清理对象
如我们删除一个类的指针对象,则自动调用析构函数:
sales_item是一个类
sales_item *p = new sales_item //建立并分配一个类的指针p
delete p;//这就是撤消类的对象,随后它自动调用析构函数
2.定义
构造函数名和类名完全一样,并在名字前面加\"~\"符号
每个类只有一个析构函数
2.1定义格式
~析构函数名称(){} //一般析构函数:
virtual ~析构函数名称(){} //虚析构函数:
代码如下
class item{
public:
~item(){}
};
3 基类与派生类
3.1一般基类是不用写出析构函数,编译器自动添加一个
类aa可以正常的工作就是编译器自动添加了四个函数
如代码
class aa{
public:
//构造,析构,复制构造,赋值操作符四个函数由编译器自动添加
int getx(){return x;}
void set(int a){x=a;}
private:
int x;
};
3.2析构函数\"三法则\",如果类中有复制构造函数和赋值操作符重载,则析构函数必须要,三者缺一不可
class bb{
public:
bb(const bb& rhs){...} //复制构造函数
bb& operator=(const bb& rhs){...} //赋值操作符
~bb(){清理函数} //析构函数
private:
int x
};
以上三个函数三者必须同时出现,以免出现有的对象清除不了,有的出现\"浅复制错误\"
3.3如果类中有指针成员,则必须专门写一个析构函数来清理指针成员,编译器默认添加的析构函数不会去清理指针对象
如果类中有指针成员,如链表结构实现等,
指针成员是基本单位,在方便使用指针的同时,如何管理好它们的工作就是C++中最困难的部分
这个析构函数最好特别定制,做法是析构函数加一个清理函数,析构函数直接调用它就OK
3.4派生类
虚成员函数和虚析构函数通常是成对出现
当基类有虚函数时,派生类会发生动态调用,也就是动态绑定,
当不知道是调用基类对象还是调用派生类对象时,还要正确的清理它们就更加困难啦,在基类引入虚析构函数后,
它也能发生动态绑定,正确的清理对象,这些都要到程序运行后才能知道调用对象,在编译前是无法知道对象是谁的
代码:
//基类
class base{
public:
virtual draw(){}; //虚方法
virtual ~base(){};//虚析构函数
};
//派生类
class dev : public base{
public:
draw(){}//draw方法的实现
~dev(){}//析构函数
};
4.设计指导
4.1一般的类我们不需要设计出它的析构函数,编译器自动为我们构建一个析构函数
4.2析构函数\"三法则\",如果类中有复制构造函数和赋值操作符重载,则析构函数必须要,三者缺一不可
4.3如果类中有指针成员,则必须专门写一个析构函数来清理指针成员,编译器默认添加的析构函数不会去清理指针对象
4.4\"虚函数和虚析构函数成对实现\",
当类中有虚成员时,定制虚析构函数,让派生类实行动态绑定方式来清除基类对象或者派生类对象