zoukankan      html  css  js  c++  java
  • 转()析构函数

    为什么要说“也”?用google搜索“析构函数”是,google会说“约有81,500项符合 析构函数 的查询结果”,我最近复习c++是有所心得,所以“也”想谈谈“析构函数”。我不想像教科书似的介绍它,而是从它何时被调用来浅谈一下。

    析构函数在下边3种情况时被调用:
    1.对象生命周期结束,被销毁时;
    2.delete指向对象的指针时,或delete指向对象的基类类型指针,而其基类虚构函数是虚函数时;
    3.对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。

    情况1请看下边代码:
    #include<iostream.h>
    class A
    {
     public:
     A()
     {
      cout<<"constructing A"<<endl;
     } 
     ~A()
     {
      cout<<"destructing A"<<endl;
     }
     private:
     int a;
    };
    class B: public A
    {
     public:
     B()
     {
      cout<<"constructing B"<<endl;
     }
     ~B()
     {
      cout<<"destructing B"<<endl;
     }
     private:
     int b;
    };

    void main()
    {
     B b;
    }

    运行结果为:

    constructing A
    constructing B
    destructing B
    destructing A

    上述代码还说明了一件事:析构函数的调用顺序与构造函数的调用顺序相反。

    情况2则正好说明了为什么基类应该把析构函数声明为虚函数,请先看下边的例子:

    #include<iostream.h>
    class A
    {
     public:
     A()
     {
      cout<<"constructing A"<<endl;
     } 
     ~A()
     {
      cout<<"destructing A"<<endl;
     }
     private:
     int a;
    };
    class B: public A
    {
     public:
     B()
     {
      cout<<"constructing B"<<endl;
     }
     ~B()
     {
      cout<<"destructing B"<<endl;
     }
     private:
     int b;
    };

    void main()
    {
     A* a = new B;
     delete a;
    }

    运行结果为:

    constructing A
    constructing B
    destructing A

    若将class A中的析构函数声明为虚函数,运行结果将变成:

    constructing A
    constructing B
    destructing B
    destructing A

    由此还可以看出虚函数还是多态的基础,才c++中没有虚函数就无法实现多态。因为不声明成虚函数就不能“推迟联编”,所以不能实现多态。这点上和java不同,java总是“推迟联编”的,所以也剩了这些麻烦。

    扯远了,再看情况3,通过下边代码表示:
    #include<iostream.h>
    class A
    {
     public:
     A()
     {
      cout<<"constructing A"<<endl;
     }
     ~A()
     {
      cout<<"destructing A"<<endl;
     }
     private:
     int a;
    };

    class C
    {
     public:
     C()
     {
      cout<<"constructing C"<<endl;
     }
     ~C()
     {
      cout<<"destructing C"<<endl;
     }
     private:
      int c;
    };

    class B: public A
    {
     public:
     B()
     {
      cout<<"constructing B"<<endl;
     }
     ~B()
     {
      cout<<"destructing B"<<endl;
     }
     private:
     int b;
     C c;
    };

    void main()
    {
     B b;
    }

    运行结果为:

    constructing A
    constructing C
    constructing B
    destructing B
    destructing C
    destructing A

    b的析构函数调用之后,又调用了b的成员c的析构函数,同时再次验证了析构函数的调用顺序与构造函数的调用顺序相反。

    若将上边的代码中的main()函数内容改成

     A* a = new B;
     delete a;
     
    由情况2我们知道,这将不会调用class B的析构函数不会被调用,所以class C的析构函数也不会被调用。
    正如我们想的,运行结果为:

    constructing A
    constructing C
    constructing B
    destructing A

    俗话说温故而知新,我却不想做什么师,只是希望能够和大家分享一下对析构函数和虚析构函数的更深的认识。以上代码在VC++6.0上测试通过,如有疏漏或错误的认识请大家指正:)

  • 相关阅读:
    2018-6-2_《JS操作数组(纯洁方法)》
    Centos7 xfs分区格式化挂载
    centos 常用命令集锦
    docker1.12在cento7里的组建swarm (一)
    centos7线程、文件打开数等调优日志(非优化案例、仅仅是个个人记录、为把相关配置文件记录一下)
    Centos7.2 新镜像、系统到手 更新清理 并且安装docker1.2以后版本 目前内容适合docker 1.7.x ce(社区版)
    程序员新手 0年份等级 指导(一) 开发人员IT架构总览
    docker 土法制作zookeeper镜像 并且搭建集群 基于centos7.2
    centos 删除多余的内核启动项
    docker1.12在cento7里的组件swarm (二)
  • 原文地址:https://www.cnblogs.com/duerbin/p/3443408.html
Copyright © 2011-2022 走看看