首先我们知道虚函数是实现运行期的多态的。
根据类型兼容原则,在需要基类指针的地方,都可以用派生类的指针去代替。
如下代码,就实现了多态。
#include<bits/stdc++.h>
using namespace std;
class A{
public:
A(){
}
~A(){
}
virtual void fun(){
cout<<1<<endl;
}
};
class B:public A{
public:
B(){
}
~B(){
}
virtual void fun(){
cout<<2<<endl;
}
};
int main(){
A* testA=new A();
testA->fun();
delete testA;
A* testB=new B();
testB->fun();
delete testB;
return 0;
}
输出:
其实,上面代码是存在内存泄漏的。
我们把类A和类B的析构函数加上输出看看
#include<bits/stdc++.h>
using namespace std;
class A{
public:
A(){
}
~A(){
cout<<"A over"<<endl;
}
virtual void fun(){
cout<<1<<endl;
}
};
class B:public A{
public:
B(){
}
~B(){
cout<<"B over"<<endl;
}
virtual void fun(){
cout<<2<<endl;
}
};
int main(){
A* testA=new A();
testA->fun();
delete testA;
cout<<endl;
A* testB=new B();
testB->fun();
delete testB;
return 0;
}
输出:
可以发现testA没有问题。
但是testB只有类A部分被析构了,而类B还没有析构,这里存在了内存泄漏
那么将析构函数定义为虚函数后呢
#include<bits/stdc++.h>
using namespace std;
class A{
public:
A(){
}
virtual ~A(){
cout<<"A over"<<endl;
}
virtual void fun(){
cout<<1<<endl;
}
};
class B:public A{
public:
B(){
}
virtual ~B(){
cout<<"B over"<<endl;
}
virtual void fun(){
cout<<2<<endl;
}
};
int main(){
A* testA=new A();
testA->fun();
delete testA;
cout<<endl;
A* testB=new B();
testB->fun();
delete testB;
return 0;
}
输出:
这样就没有问题了
所以,将析构函数设为虚函数,是为了防止内存泄漏。
如果存在用基类指针指向派生类对象,这样子可以使得基类和派生类的析构函数都被调用,不会造成内存泄漏。如果不把析构函数定义为虚函数,那么只会调用基类的析构函数。