zoukankan      html  css  js  c++  java
  • 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
    从这个程序运行不难看出,析构函数的调用顺序与构造函数调用顺序正好是相反的,为了方便记忆,我们可以将之理解为一个栈,先入后出。

    类的构造函数负责对象完成初始化及其它相关操作,而析构函数则用于销毁对象时完成相应的资源释放工作。在设计类过程中,我们建议为每个带有成员变量的类设计一个默认构造函数,其它构造函数及析构函数则可以视情况再定。
     
  • 相关阅读:
    解决xcode5升级后,Undefined symbols for architecture arm64:问题
    第8章 Foundation Kit介绍
    app 之间发送文件 ios
    iphone怎么检测屏幕是否被点亮 (用UIApplication的Delegate)
    CRM下载对象一直处于Wait状态的原因
    错误消息Customer classification does not exist when downloading
    How to resolve error message Distribution channel is not allowed for sales
    ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX这些东东是什么鬼
    有了Debug权限就能干坏事?小心了,你的一举一动尽在系统监控中
    SAP GUI和Windows注册表
  • 原文地址:https://www.cnblogs.com/yongpan/p/7481318.html
Copyright © 2011-2022 走看看