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时执行析构函数。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java初学

static关键字

308100
来自专栏java初学

5.7 (2)反射举例

389120
来自专栏程序员互动联盟

【java基础】匿名类

昨天后台的一个小伙伴提到了,java里面的匿名类,这个概念在平常java码代码的时候用的特别多,所以找了一篇介绍表述比较清晰的文章分享给大家,能极大的简化代码量...

37870
来自专栏C/C++基础

C++11继承构造函数

子类为完成基类初始化,在C++11之前,需要在初始化列表调用基类的构造函数,从而完成构造函数的传递。如果基类拥有多个构造函数,那么子类也需要实现多个与基类构造函...

17220
来自专栏土豆专栏

Java面试之关键字

finalize()是Object的protected方法,子类可以覆盖该方法来实现资源清理工作,GC在回收对象之前调用该方法。

239100
来自专栏用户2442861的专栏

Java finally语句到底是在return之前还是之后执行?

网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正...

22420
来自专栏calmound

Javascript数组

定义    定义空数组       var arr = new Array();       var arr = [];    定义一个包含1,2,3的数组  ...

35560
来自专栏十月梦想

each()list()while遍历数组

each()函数:需要一个数组作为参考,each函数返回1,0,key,value键值,0,key返回键,1,value对应的值,

11010
来自专栏racaljk

正则表达式

\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配字符“n”。“\\n”匹配一个换行符。序列“\\...

11350
来自专栏编程

带你深入理解Python属性查找

今天扣丁学堂给大家介绍一下关于python视频教程中的属性查找,首先在Python中属性查找(attributelookup)是比较复杂的,特别是涉及到描述符d...

20590

扫码关注云+社区

领取腾讯云代金券