C++之虚析构函数

来源:互联网 发布:2016淘宝详情尺寸大小 编辑:程序博客网 时间:2024/06/13 07:58

       相信大家都已经清楚了虚函数这个概念。在C++中,构造函数不能声明为虚函数,而析构函数却可以声明为虚函数,大家可能对为什么要把析构函数声明为虚函数很疑惑,下面,云主(博主)就带大家去会会这个虚析构函数

首先,先看一段代码:

#incldue <iostream>

using namespace std;

class Base

{

private:

int *pb;

public:

Base(){ pb = new int(1); }//构造函数

  ~Base(){ delete pb; 

      cout<<"Base destructor!!"<<endl; 

}//析构函数

};


class Derive : public Base

{

private:

int *pd;

public:

Derive() : Base() { pd = new int(2) }

~Derive(){ delete pd; 

cout<<"Derive destructor!!"<<endl;

}

};


int main()

{

Base *p = new Derive();

delete p;//delete时会调用析构函数


return 0;

}


很显然,上面的程序输出结果是:Base destructor!!。

下面,画个图来说明一下

此图适合无虚函数的内存模型,有虚函数时应该再加上虚表指针。


图中大致可以得出:用基类指针指向派生类对象,此时正常指针可以访问到的是基类自己的成员和虚函数。显然这里在执行语句delete p时,调用的是Base类的析构函数,从而只是释放了pb,而pd仍然在堆中(因为没用调用派生类的析构函数),那么就造成了内存泄露。

如果,将Base类中的析构函数声明为虚函数,即:virtual ~Base(),此时无论派生类中的析构函数有没有加关键字virtual,它都是虚函数。

那么,到这里,我们就清楚了。在delete  p时,根据多态的虚表,它调用的是派生类的析构函数,即~Derive(); 而派生类的析构函数会自动调用基类的析构函数。所以,会先释放pd,再释放pb,最后释放p;这样,动态申请的内存的内存就全部被释放了。

小结:若一个类有派生类,则应将这个类设计为多态类。若这个类中没有要设计成多态的成员函数,则至少应该析构函数声明为虚函数。


以上内容是云主学习C++过程中的一些体会。毕竟能力有限,若有错误之处,还望指正:  singlecui@126.com

0 0