dengnilikai

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

说明以下程序的显示结果:

#include <iostream>
using namespace std;

class A
{
public:
        A() {cout<<"This is A()"<<endl;}
        ~A() {cout<<"This is ~A()"<<endl;}
        virtual void hello()
        {
                cout<<"Hello A"<<endl;
        }
};

class B:public A
{
public:
        B() {cout<<"This is B()"<<endl;}
        ~B() {cout<<"this is ~B()"<<endl;}
        void hello()
        {
                cout<<"Hello B"<< endl;
        }
};

int main()
{
        A *ptr = (A *)new B();
        //B *ptr = new B();
        ptr->hello();
        delete ptr;
        return 0;
}

 

显示结果:

This is A()
This is B()
Hello B
This is ~A()

即没有调用B的析构函数

解析:

一般情况下构造函数调用父类-》子类;析构函数调用子类-》父类

比如这么写

 B *ptr=new B(); 先  析构 B类 再析构A类

但如果是上面那种写法

A *ptr=(A *)new B();

...

delete ptr;  

结果就是构造函数相同,析构函数只调用A,因为ptr的类型是A,delete ptr时将调用类型A的析构函数;没析构B,造成内存泄露

一般遇到这样的现象,需要将基类的析构函数定义为虚拟的

这样的话,情况就是:析构函数调用过程为子类->父类,不过内部原理不一样 delete ptr时调用类型A的析构函数步骤如下:
1,到虚函数映射表中查找A的实际析构函数;
2,发现被实例化为B的析构函数;
3,调用B的析构函数;
4,调用A的析构函数--如果A的析构不是纯虚函数的话

运行结果为:

This is A()
This is B()
Hello B
this is ~B()
This is ~A()

即调用了B的析构函数

 

另这里基类的hello()函数是虚函数,所以ptr->hello()用的是子类的hello()函数,如果基类的hello()不是虚函数,则会调用基类的hello()

 

posted on 2016-04-21 21:15  dengnilikai  阅读(337)  评论(0编辑  收藏  举报