• 转:析构函数


    析构函数在下边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


    原文地址:http://blog.csdn.net/weizhee/article/details/562833

  • 相关阅读:
    C#界面交互Invoke的便捷写法
    C#简单线程同步例子
    输出一个数据库中所有表的数据量
    JavaScript 解析xml字符串
    图片与Byte流互转
    html中name 和 id 的区别
    JavaScript 解析xml文件
    关于序列化的使用
    js 动态创建xml串
    js动态删除节点
  • 原文地址:https://www.cnblogs.com/mliudong/p/3244365.html
Copyright © 2020-2023  润新知