简介:析构函数定义为virtual虚函数,有什么作用?
简单的说,C++中基类采用virtual虚析构函数是为了防止内存泄漏,如果派生类中申请了内存空间,并在析构函数中对这些内存空间进行了释放。
如果这个时候基类中采取的是非虚构函数,那么当删除基类指针的死后,指向派生类对象的时候就不会发生动态绑定,导致的结果就是,调用基类的析构函数,而不会调用派生类的析构函数。
再这样的情况下对于派生类申请的空间就得不到释放从而产生了内存泄漏。
为了防止这样的情况发生,C++中基类的析构函数就需要采取virtual的虚构函数,实现动态绑定,这样才可以。
至于什么是动态绑定与静态绑定可以看看这篇文章:动态多态与静态多态
学习代码:
#include<iostream>
using namespace std;
class A
{
public:
A(){
}
~A(){
cout << "A discontruct" << endl;
}
virtual string OnPaint() = 0; // 定义接口
};
class B : public A
{
public:
virtual string OnPaint()
{
cout<< "B" << endl;
return "B";
}
~B(){
cout << "B discontruct" << endl;
}
};
class C : public A
{
public:
virtual string OnPaint()
{
cout<< "C" << endl;
return "C";
}
~C(){
cout << "C discontruct" << endl;
}
};
int main()
{
A* p = new B();
p->OnPaint(); // B
delete p;
p = new C();
p->OnPaint(); // C
delete p;
return 0;
}
运行结果
通过运行结果我们可以发现,派生类的内存没有得到释放。
改进办法
#include<iostream>
using namespace std;
class A
{
public:
A(){
}
virtual ~A(){
cout << "A discontruct" << endl;
}
virtual string OnPaint() = 0; // 定义接口
};
class B : public A
{
public:
virtual string OnPaint()
{
cout<< "B" << endl;
return "B";
}
virtual ~B(){
cout << "B discontruct" << endl;
}
};
class C : public A
{
public:
virtual string OnPaint()
{
cout<< "C" << endl;
return "C";
}
virtual ~C(){
cout << "C discontruct" << endl;
}
};
int main()
{
A* p = new B();
p->OnPaint(); // B
delete p;
p = new C();
p->OnPaint(); // C
delete p;
return 0;
}
运行结果
通过把析构函数定义为虚函数,实现了派生类的内存释放。