14 对象的销毁

1 问题

  • C++ 如何清理需要销毁的对象?

2 对象的销毁

  • 一般而言,需要销毁的对象都应该做清理

  • 解决方案

    • 为每个类都提供一个 publicfree 函数
    • 对象不再需要时立即调用 free 函数进行清理
    class Test
    {
        int* p;
    public:
        Test(){
            p = new int;
        }
        void free(){
            delete p;
        }
    };
    
  • 存在的问题

    • free 只是一个普通的函数,必须显式地调用
    • 对象销毁前没有做清理,很可能造成资源泄漏
  • C++ 编译器是否能够自动调用某个特殊的函数进行对象的清理?

    • 析构函数

3 析构函数

  • C++ 的类中可以定义一个特殊的清理函数

    • 称为析构函数
    • 功能与构造函数相反
  • 定义:~ClassName()

    • 析构函数没有参数也没有返回值类型声明
    • 析构函数在对象销毁时自动被调用
  • 示例:析构函数

    • Demo

      #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;
      }
      
    • 编译运行

      Test(): 1
      Test(): 2
      ~Test(): 2
      ~Test(): 1
      
  • IntArray 类的改进

    • Demo

      //IntArray.h
      #ifndef _INTARRAY_H_
      #define _INTARRAY_H_
      
      class IntArray
      {
      private:
          int m_length;
          int* m_pointer;
      public:
          IntArray(int len);
          IntArray(const IntArray& obj);
          int length();
          bool get(int index, int& value);
          bool set(int index ,int value);
          ~IntArray(); //析构函数
      };
      
      #endif
      
      
      //IntArray.cpp
      #include "IntArray.h"
      
      IntArray::IntArray(int len)
      {
          m_pointer = new int[len];
          
          for(int i=0; i<len; i++)
          {
              m_pointer[i] = 0;
          }
          
          m_length = len;
      }
      
      IntArray::IntArray(const IntArray& obj)
      {
          m_length = obj.m_length;
          
          m_pointer = new int[obj.m_length];
          
          for(int i=0; i<obj.m_length; i++)
          {
              m_pointer[i] = obj.m_pointer[i];
          }
      }
      
      int IntArray::length()
      {
          return m_length;
      }
      
      bool IntArray::get(int index, int& value)
      {
          bool ret = (0 <= index) && (index < length());
          
          if( ret )
          {
              value = m_pointer[index];
          }
          
          return ret;
      }
      
      bool IntArray::set(int index, int value)
      {
          bool ret = (0 <= index) && (index < length());
          
          if( ret )
          {
              m_pointer[index] = value;
          }
          
          return ret;
      }
      
      IntArray::~IntArray()
      {
          delete[] m_pointer;
      }
      
  • 析构函数的定义准则

    • 当类中自定义了构造函数,并且构造函数中使用了系统资源(如:内存申请,文件打开等),则需要自定义析构函数
原文地址:https://www.cnblogs.com/bky-hbq/p/13717747.html