zoukankan      html  css  js  c++  java
  • C++对析构函数的误解(转)

    C++析构前言

    析构函数在什么时候会自动被调用,在什么时候需要手动来调用,真不好意思说偶学过C++…今日特此拨乱反正

    C++析构误解正文

    对象在构造的时候系统会分配内存资源,对一些数据成员进行初始化或者赋值;一个良好的class需要有资源回收的机制,而这一操作便落在了析构函数的头上,析构函数来负责类内的资源的free。来看一段代码:

    class myclass
    {
        public:
            myclass()
            {
                cout << "构造函数" <<endl;
            }
            ~myclass()
            {
                cout << "析构函数" <<endl;
            }
    };
    
    int main()
    {
        myclass mc;
        return 0;
    }

    执行结果:

    图1

    在main主函数当中,如果直接声明一个对象,在声明的时候,直接就调用了类内的构造函数,在主函数结束之前的那一小刻,也自动调用了这个类的析构函数;在看一段代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using  namespace std;
    
    class myclass
    {
        public:
            myclass()
            {
                cout << "构造函数" <<endl;
            }
            ~myclass()
            {
                cout << "析构函数" <<endl;
            }
    };
    
    int main()
    {
        myclass *mc;
        return 0;
    }

     执行结果:

    在main主函数当中,如果直接声明一个对象指针(只是声明而已),既不自动调用构造函数和析构函数。但是将main函数改为下面:

    class myclass
    {
        public:
            myclass()
            {
                cout << "构造函数" <<endl;
            }
            ~myclass()
            {
                cout << "析构函数" <<endl;
            }
    };
    
    int main()
    {
        myclass *mc;
        mc =new myclass();
        return 0;
    }

    执行结果:

    这里不仅声明了一个对象指针,而且new了,这说明给这一对象指针分配一个内存空间,当然这就会调用构造函数了;咦,奇怪了,为什么不自动调用析构函数了,说明C++内部缺少这一机制,C++毫不客气的对你说:“你提醒我给一个对象分配空间,那也得麻烦你提醒我将它释放(delete)。于是便有:

    class myclass
    {
        public:
            myclass()
            {
                cout << "构造函数" <<endl;
            }
            ~myclass()
            {
                cout << "析构函数" <<endl;
            }
    };
    
    int main()
    {
        myclass *mc;
        mc =new myclass();
        delete mc;
        return 0;
    }

    执行结果:

    图1

    所以如果是指针在new之后需要手动释放资源。在较大型的工程当中,资源的释放很重要,因为涉及的数据量比较多,稍有不慎,就会造成资源的浪费和泄露之类的问题,从现在起你就应该养成把握资源的好习惯。


    条款20:宁以pass-by-reference-to-const替换pass-by-value。——Scott Meyers

    //即:宁可用(常)引用传递替换值传递。

    为什么要在这里说在函数当中使用“常引用”,固然它跟析构函数有很大的牵连。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using  namespace std;
    
    class myclass
    {
        public:
            myclass()
            {
                cout << "构造函数" <<endl;
            }
            ~myclass()
            {
                cout << "析构函数" <<endl;
            }
    
    };
    
    void fx(myclass mc)
    {
    
    }
    
    int main()
    {
        myclass mc;
        fx(mc);
        return 0;
    }

    执行结果:

    结果很明朗,function函数内对myclass类的对象mc作了一次复制(浅复制而已)而造出了另一个对象,也就是函数内的对象副本;调用函数的时候,如果选择是传值调用,那么会有参数副本被复制到函数的栈区。

    因为这里调用的myclass类默认的copy构造函数,而不是调用上面myclass类的构造函数,但我们都明白,无论是哪种,都了构造,都是需要花费时间的,先不管时间有多短;遇上析构函数那是必然的。再者,如果myclass类有n个父类,而它的父类又有几个参数需要构造析构,最后还需要层层析构......那这个花费的时间可就不能四舍五入啦。

    解决方法就是宁以pass-by-reference-to-const替换pass-by-value。我们这样:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using  namespace std;
    
    class myclass
    {
        public:
            myclass()
            {
                cout << "构造函数" <<endl;
            }
            ~myclass()
            {
                cout << "析构函数" <<endl;
            }
    
    };
    
    void fx(const myclass &mc)
    {
    
    }
    
    int main()
    {
        myclass mc;
        fx(mc);
        return 0;
    }

    结果让我们大吃一惊:

    这就是我们想要,而如果你怕function函数内会对mc做一些非法的事情,const可以把他拒之门外。太帅了,实在是太帅了。

  • 相关阅读:
    Microsoft Enterprise Library 5.0 系列(二) Cryptography Application Block (初级)
    Microsoft Enterprise Library 5.0 系列(五) Data Access Application Block
    Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception
    Microsoft Enterprise Library 5.0 系列(九) Policy Injection Application Block
    Microsoft Enterprise Library 5.0 系列(三) Validation Application Block (高级)
    软件研发打油诗祝大家节日快乐
    从挖井的故事中想到开发管理中最容易忽视的几个简单道理
    ITIL管理思想的执行工具发布
    管理类软件设计“渔”之演化
    20070926日下午工作流与ITILQQ群 事件管理 讨论聊天记录
  • 原文地址:https://www.cnblogs.com/kane0526/p/3585338.html
Copyright © 2011-2022 走看看