• 第22课对象的销毁


    对象的销毁
    生活中的对象都是被初始化后才上市的(从而引入了构造函数)
    生活中的对象被销毁前会做一些清理工作
    问题:
    C++中如何清理需要销毁的对象
    一般而言,需要销毁的对象都应该做清理
    解决方案
      为每个类都提供一个public的free函数
      对象不再需要时立即调用free函数进行清理
    class Test
    {
    int *p;
    public:
      Test() { p = new int; }
      void free() { delete p; };
    };

    存在的问题
    free只是一个普通的函数,必须显示的调用
    对象销毁前没有做清理工作,很可能造成资源泄露

    C++编译器是否能够自动调用某个特殊的函数进行对象的清理?

    析构函数闪亮登场了
    C++的类中可以定义一个特殊的清理函数
    这个特殊的清理函数叫做析构函数
    析构函数的功能与构造函数相反
    定义:~ClassName()
    析构函数没有参数也没有返回值类型声明
    析构函数在对象销毁时自动被调用

    析构函数使用初探:

     1 #include <stdio.h>
     2 
     3 class Test
     4 {
     5 public:
     6     Test()
     7     {
     8         printf("Test(): 
    ");
     9     }      
    10 
    11     ~Test()
    12      {
    13          printf("~Test(): 
    ");
    14      }
    15 
    16 };    
    17 
    18 int main()
    19 {
    20      Test t;
    21      
    22       return 0;

    该试验表明,析构函数会被自动调用。

    #include <stdio.h>
    
    class Test
    {
        int mi;
    public:
        Test(int i)
        {
            mi = i;
            printf("Test(): %d
    ", mi);
        }
        ~Test()
        {
            printf("~Test(): %d
    ", mi);
        }
    };
    
    int main()
    {
        Test t(1);
        
        Test* pt = new Test(2);
        
        delete pt;
        
        return 0;
    }

    将以前实现的那个数组程序继续改进:

     1 #ifndef _INTARRAY_H_
     2 #define _INTARRAY_H_
     3 
     4 class IntArray
     5 {
     6 private:
     7     int m_length;
     8     int* m_pointer;
     9 public:
    10     IntArray(int len);
    11     IntArray(const IntArray& obj);
    12     int length();
    13     bool get(int index, int& value);
    14     bool set(int index ,int value);
    15     ~IntArray();
    16 };
    17 
    18 #endif

     1 #include "IntArray.h"
     2 
     3 IntArray::IntArray(int len)
     4 {
     5     m_pointer = new int[len];
     6     
     7     for(int i=0; i<len; i++)
     8     {
     9         m_pointer[i] = 0;
    10     }
    11     
    12     m_length = len;
    13 }
    14 
    15 IntArray::IntArray(const IntArray& obj)
    16 {
    17     m_length = obj.m_length;
    18     
    19     m_pointer = new int[obj.m_length];
    20     
    21     for(int i=0; i<obj.m_length; i++)
    22     {
    23         m_pointer[i] = obj.m_pointer[i];
    24     }
    25 }
    26 
    27 int IntArray::length()
    28 {
    29     return m_length;
    30 }
    31 
    32 bool IntArray::get(int index, int& value)
    33 {
    34     bool ret = (0 <= index) && (index < length());
    35     
    36     if( ret )
    37     {
    38         value = m_pointer[index];
    39     }
    40     
    41     return ret;
    42 }
    43 
    44 bool IntArray::set(int index, int value)
    45 {
    46     bool ret = (0 <= index) && (index < length());
    47     
    48     if( ret )
    49     {
    50         m_pointer[index] = value;
    51     }
    52     
    53     return ret;
    54 }
    55 
    56 IntArray::~IntArray()
    57 {
    58     delete[]m_pointer;
    59 }
     1 #include <stdio.h>
     2 #include "IntArray.h"
     3 
     4 int main()
     5 {
     6     IntArray a(5);    
     7     
     8     for(int i=0; i<a.length(); i++)
     9     {
    10         a.set(i, i + 1);
    11     }
    12     
    13     for(int i=0; i<a.length(); i++)
    14     {
    15         int value = 0;
    16         
    17         if( a.get(i, value) )
    18         {
    19             printf("a[%d] = %d
    ", i, value);
    20         }
    21     }
    22     
    23     IntArray b = a;
    24     
    25     for(int i=0; i<b.length(); i++)
    26     {
    27         int value = 0;
    28         
    29         if( b.get(i, value) )
    30         {
    31             printf("b[%d] = %d
    ", i, value);
    32         }
    33     }
    34     
    35     return 0;
    36 }


    析构函数的定义准则
    当类中自定义了构造函数,并且构造函数中使用了系统资源(如:申请内存,文件打开,等),则需要自定义析构函数

    小结:
    析构函数是对象销毁时进行清理的特殊函数
    析构函数在对象销毁时自动被调用
    析构函数是对象释放系统资源的保障

  • 相关阅读:
    android 源码编译 问题 列表
    springboot总结
    设计模式学习笔记
    JWT入门1
    oauth2入门github
    mybatis面试题
    shiro入门
    knife4j swagger API文档
    pahole安装(编译)
    goMySql的逆向工程
  • 原文地址:https://www.cnblogs.com/-glb/p/11853741.html
Copyright © 2020-2023  润新知