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

    int main()
    {
        myclass * mc;
        return 0;
    }

     执行结果:

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

    int main()
    {
        myclass * mc;
        mc = new myclass();
        return 0;
    }

    执行结果:

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

    int main()
    {
        myclass * mc;
        mc = new myclass();
        delete mc;
        return 0;
    }

    执行结果:

    图1

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


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

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

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

    执行结果:

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

    因为这里调用的myclass类默认的copy构造函数,而不是调用上面myclass类的构造函数,但我们都明白,无论是哪种,都调用了构造,都是需要花费时间的,先不管时间有多短;遇上析构函数那是必然的。再者,如果myclass类有n个父类,而它的父类又有几个参数需要构造析构,最后还需要层层析构(virtual析构函数《C++虚函数和纯虚函数(1)》)......那这个花费的时间可就不能四舍五入啦。(注:这里要去查下资料,看是否有关于子类何时调用父类的构造函数、析构函数???)

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

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

     

    结果让我们大吃一惊:

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

    转自:http://www.cnblogs.com/daoluanxiaozi/archive/2011/12/09/2281796.html

  • 相关阅读:
    Vsftpd 3.0.2 正式版发布
    Putdb WebBuilder 6.5 正式版本发布
    SoaBox 1.1.6 GA 发布,SOA 模拟环境
    pynag 0.4.6 发布,Nagios配置和插件管理
    Percona Playback 0.4,MySQL 负荷回放工具
    xombrero 1.3.1 发布,微型 Web 浏览器
    Hypertable 0.9.6.4 发布,分布式数据库
    libmemcached 1.0.11 发布
    CryptoHeaven 3.7 发布,安全邮件解决方案
    Android Activity生命周期
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/5798533.html
Copyright © 2011-2022 走看看