• 2.14 C++析构函数


    参考: http://www.weixueyuan.net/view/6345.html

    总结:
      析构函数就是用于回收创建对象时所消耗的各种资源。
      析构函数的调用顺序与构造函数调用顺序正好是相反的。
      类的构造函数负责对象完成初始化及其它相关操作,而析构函数则用于销毁对象时完成相应的资源释放工作。
     
    在创建对象的时候系统会自动调用构造函数,在对象需要被销毁的时候同样系统会自动调用一个函数,这个函数被称之为析构函数。析构函数就是用于回收创建对象时所消耗的各种资源。与构造函数类似,析构函数也是一个成员函数。析构函数与普通成员函数相比,有如下特征:
    • 无返回值
    • 没有参数,不能被重载,因此一个类也只能含有一个析构函数
    • 函数名必须为“~类名”的形式,符号“~”与类名之间可以有空格

    在上一节的Array类中,我们没有在类中声明析构函数,在此,我们将其补全如下。

    例1:
     
    #include<iostream>
    using namespace std;
    
    class Array
    {
    public:
        Array(){length = 0; num = NULL;};
        Array(int * A, int n);
        Array(Array &a);
        void setnum(int value, int index);
        int * getaddress();
        void display();
        int getlength(){return length;}
        ~Array();
    private:
        int length;
        int * num;
    };
    
    Array::~Array()
    {
        if(num != NULL)
            delete[] num;
        cout<<"destructor"<<endl;
    }
    
    Array::Array(Array & a)
    {
        if(a.num != NULL)
        {
            length = a.length;
            num = new int[length];
            for(int i=0; i<length; i++)
                num[i] = a.num[i];
        }
        else
        {
            length = 0;
            num = 0;
        }  
    }
    
    Array::Array(int *A, int n)
    {
        num = new int[n];
        length = n;
        for(int i=0; i<n; i++)
            num[i] = A[i];
    }
    
    void Array::setnum(int value, int index)
    {
        if(index < length)
            num[index] = value;
        else
            cout<<"index out of range!"<<endl;
    }
    
    void Array::display()
    {
        for(int i=0; i<length; i++)
            cout<<num[i]<<" ";
        cout<<endl;
    }
    
    int * Array::getaddress()
    {
        return num;
    }
    
    int main()
    {
        int A[5] = {1,2,3,4,5};
        Array arr1(A, 5);
        arr1.display();
        Array arr2(arr1);
        arr2.display();
        arr2.setnum(8,2);
        arr1.display();
        arr2.display();
        cout<<arr1.getaddress()<<" "<<arr2.getaddress()<<endl;
        return 0;
    }
    这个例子,现在是一个完整的例子,在这个例子中,我们为其增添了一个析构函数~Array,该函数在main函数退出前被系统自动调用,用于释放num所指向的内存空间。因为有两个对象,因此最终析构函数被调用了两次。

    说到析构函数,则其调用顺序则不得不介绍一下了。析构函数与构造函数调用顺序是反转过来的,先调用构造函数的后调用构造函数。我们通过下面的例子来加以说明。

    例2:
    #include<iostream>
    using namespace std;
    
    class test
    {
    public:
        test(int i){num = i;cout<<num<<" Constructor"<<endl;}
        ~test(){cout<<num<<" Destructor"<<endl;}
    private:
        int num;
    };
    
    int main()
    {
        test t0(0);
        test t1(1);
        test t2(2);
        test t3(3);
        return 0;
    }
     
    程序运行结果:
    0  Constructor
    1  Constructor
    2  Constructor
    3  Constructor
    3  Destructor
    2  Destructor
    1  Destructor
    0  Destructor
    从这个程序运行不难看出,析构函数的调用顺序与构造函数调用顺序正好是相反的,为了方便记忆,我们可以将之理解为一个栈,先入后出。

    类的构造函数负责对象完成初始化及其它相关操作,而析构函数则用于销毁对象时完成相应的资源释放工作。在设计类过程中,我们建议为每个带有成员变量的类设计一个默认构造函数,其它构造函数及析构函数则可以视情况再定。
     
  • 相关阅读:
    「mysql优化专题」90%程序员面试都用得上的索引优化手册(5)
    「mysql优化专题」你们要的多表查询优化来啦!请查收(4)
    「mysql优化专题」单表查询优化的一些小总结,非索引设计(3)
    mysql优化专题」90%程序员都会忽略的增删改优化(2)
    「mysql优化专题」这大概是一篇最好的mysql优化入门文章(1)
    zookeeper
    linux查看进程是否存在,不存在则重启
    mysql导出文本文件,加分隔符
    oracle查看表空间和物理文件大小
    oracle插入
  • 原文地址:https://www.cnblogs.com/yongpan/p/7481318.html
Copyright © 2020-2023  润新知