C++何时需要自定义析构函数呢?

对象销毁时  如果我们自己没有写析构方法,编译器会帮我们写一个然后调用。

那么问题来了,既然我不写,编译器会帮我写,那我干嘛要写???

有木有什么情况必须我自己写的????

处理内存的时候,也就是把之前retain的对象 都release一次


<span style="font-size:18px;">#include <iostream>
using namespace std;
 
//日期类
class Date{
    int year,month,day;
    
public:
 
    //构造方法                 初始化列表
    Date(int y,int m,int d):year(y),month(m),day(d){
        cout << "创建日期类对象都会默认被动地调用一次构造方法" << endl;
    }
    
    //对象销毁时  如果我们自己没有写析构方法,编译器会帮我们写一个然后调用
#pragma 那么问题来了,既然我不写,编译器会帮我写,那我干嘛要写???有木有什么情况必须我自己写的????处理内存的时候,也就是把之前retain的对象 都release一次
    ~Date(){
        cout << "日期对象销毁都会默认被动地调用一次析构方法 ~Date()" << endl;
    }
};
 
//员工类
class Employee{
    string name;
    Date *birthday;//声明一个指针  在构造方法里面让它指向一个对象
public:
    //构造方法
    Employee (string name):name(name){
        birthday = new Date(1989,8,8);//这里会调用日期的构造方法
        cout << "调用了员工类的构造方法" << endl;
    }
    //析构方法
    ~Employee(){
        cout << "员工对象销毁了" << endl;
    }
    
};
 
//主函数
int main(){
    Employee em("假如我是张三");
    return 0;
}</span>

运行结果如下:
<span style="font-size:18px;">创建日期类对象都会默认被动地调用一次构造方法
调用了员工类的构造方法
员工对象销毁了
Program ended with exit code: 0</span>


从运行结果可以知道创建的日期对象并没有销毁,所以有内存泄漏!肿么办?


员工销毁,员工的析构被调用。但是内存也泄漏。。。。为什么泄漏了?因为出了mian函数,员工对象销毁,两个成员变量name和日期指针birthday在员工销毁的时候弹栈了,但是birthday指针指向的堆内存并没有销毁。所以应该在指针销毁之前释放指针指向的内存空间。那么应该在哪里释放?员工对象在销毁的时候一定调用析构函数,所以在析构方法里对指针birthday进行delete,先把堆里开辟的内存空间清除掉,然后这个员工对象再销毁,所有内存才没有问题。

重写员工的析构函数如下:

 //析构方法
    ~Employee(){
        delete birthday;//清除指针指向的内存空间
        cout << "员工对象销毁了" << endl;
    }

再次运行结果如下:

创建日期类对象都会默认被动地调用一次构造方法
调用了员工类的构造方法
日期对象销毁都会默认被动地调用一次析构方法 ~Date()
员工对象销毁了
Program ended with exit code: 0


总结:析构函数,如果我们自己不写,编译器会帮我们写(编译器自己写的析构里面什么都不干)。什么时候必须要我们自己写?如果本类中一个成员变量是别的对象的指针,而且这个指针不是传进来的地址而是这个指针指向的对象,是在本类中(如果是栈里的定位分配,也不用考虑内存)在堆中开辟的空间创建的。并且该指针没有进行过delete操作,那么久需要在析构方法中进行delete操作,此时我们就必须自己写析构函数 。      

注意:    delete一个没有指向的指针会报错

全局区的对象在程序一开始就创建,程序结束才会销毁。栈区的对象在调用函数(代码块,如for循环里面)的时候才会创建,出了函数就会销毁。  在堆中开辟空间创建的对象必须我们自己手动delete。

<pre name="code" class="cpp"><pre name="code" class="cpp">//主函数
int main(){
    Employee em("假如我是张三");
    
    cout << "===== 1 栈里的对象 ======" << endl;
    for (int i = 0; i< 3; i++) {
        Date d(2015,1,23);
    }
    
    cout << "===== 2 ======" << endl;
    {
        Date d2(2015,1,2);
        Date d3(2015,1,3);
        Date d4(2015,1,5);
        cout << "===== 3 ===="<< endl;
    }
    
    cout << "=== 4 ====" << endl;
    
    {  //这个代码块里会调用几次构造方法??0次  因为这里只是创建指针并没有创建开辟空间对象
        Date *d5;
        Date *d6;
        Date *d7;
    }
    
    cout << "=== 5 ====" << endl;
    return 0;
}

运行结果:
<pre name="code" class="cpp">===== 1 栈里的对象 ======
创建日期类对象都会默认被动地调用一次构造方法
日期对象销毁都会默认被动地调用一次析构方法 ~Date()
创建日期类对象都会默认被动地调用一次构造方法
日期对象销毁都会默认被动地调用一次析构方法 ~Date()
创建日期类对象都会默认被动地调用一次构造方法
日期对象销毁都会默认被动地调用一次析构方法 ~Date()
===== 2 ======
创建日期类对象都会默认被动地调用一次构造方法
创建日期类对象都会默认被动地调用一次构造方法
创建日期类对象都会默认被动地调用一次构造方法
===== 3 ====
日期对象销毁都会默认被动地调用一次析构方法 ~Date()
日期对象销毁都会默认被动地调用一次析构方法 ~Date()
日期对象销毁都会默认被动地调用一次析构方法 ~Date()
=== 4 ====
=== 5 ====

--------------------- 
作者:iOS爱到疯 
来源:CSDN 
原文:https://blog.csdn.net/love9099/article/details/43086945 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/speargod/article/details/86635283
今日推荐