zoukankan      html  css  js  c++  java
  • C++虚析构函数解析

      当派生类对象从内存中撤销时一般先运行派生类的析构函数,然后再调用基类的析构函数。
    如果用new运算符建立的派生类的临时对象,对指向基类的指针指向这个临时对象当用delete运算符撤销对象时,系统执行的是基类的析构函数,而不是派生类的析构函数,不能彻底的“清理现场”。解决的方法是将基类及派生类的析构函数设为虚函数,这时无论基类指针指向哪个派生类对象,系统会采用动态关联,调用相应的析构函数对对象进行清理。
     
    class Point
    {
    public :
              Point(){};
              ~Point(){ std::cout << "Point destructor" << std::endl; }
     
    private :
    };
     
    class Circle: public Point
    {
    public :
              Circle(){};
              ~Circle(){ std::cout << "Circle destructor" << std::endl; };
     
    private :
    };
     
    int _tmain( int argc , _TCHAR* argv[])
    {
               Point *p = new Circle;
               delete p;
              getchar();
               return 0;
    }
    程序运行结果如下:

    下面将基类的析构函数改成虚析构函数
    virtual   ~Point(){ std::cout << "Point destructor" << std::endl; }
    其它的不变,再运行:

    这样就达到我们的目的了,基类,派生类都调用了析构函数,另外需要注意的是
    在基类的析构函数声明为虚函数时,由该基类派生的析构函数也自动成为虚函数,即使派生类的析构函数与基类的析构函数名字不相同。
     
      程序中显示的用delete运算符删除一个对象,而这个对象是指向派生类对象的基类指针,系统调用相应派生类的析构函数。
    如果程序中的局部对象离开其作用域,系统会隐式地调用其析构函数
     
    咱们增加一个函数并从写main函数:
     
    Point *fc()
    {
               Circle cl;
               Point *p = new Circle;
               return p;
    }
    int _tmain( int argc , _TCHAR* argv[])
    {
             Point *q =  fc();
               delete q;
              getchar();
               return 0;
    }
    运行结果如下:

     在上例中,函数非常fc的内部定义了两个对象:c1和p所指向的Circle类对象。对象cl在函数fc结束时执行Circle的析构函数,撤销局部变量c1.p所指向的对象的地址通过函数返回值赋予q,q所指向的对象在执行delete时执行析构函数。
  • 相关阅读:
    2020-10-03:java中satb和tlab有什么区别?
    2020-10-02:golang如何写一个插件?
    2020-10-01:谈谈golang的空结构体。
    2020-09-30:谈谈内存对齐。
    2020-09-29:介绍volatile功能。
    2020-09-28:内存屏障的汇编指令是啥?
    2020-09-27:总线锁的副作用是什么?
    2020-09-26:请问rust中的&和c++中的&有哪些区别?
    自定义刷新控件的实现原理
    scrollView的bounds
  • 原文地址:https://www.cnblogs.com/smiler/p/3872381.html
Copyright © 2011-2022 走看看