首先我们知道虚函数是实现运行期的多态的。
根据类型兼容原则,在需要基类指针的地方,都可以用派生类的指针去代替。
如下代码,就实现了多态。
#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;
}
输出:

这样就没有问题了
所以,将析构函数设为虚函数,是为了防止内存泄漏。
如果存在用基类指针指向派生类对象,这样子可以使得基类和派生类的析构函数都被调用,不会造成内存泄漏。如果不把析构函数定义为虚函数,那么只会调用基类的析构函数。
虚函数与析构函数:内存泄漏的预防之道

本文探讨了虚函数在实现运行时多态时的作用,重点阐述了如何通过将其析构函数设置为虚函数来避免内存泄漏。通过实例说明,当基类指针指向派生类对象时,若不使用虚析构,可能导致内存只被部分释放。正确使用虚析构确保了完整析构并消除内存泄露问题。
4927

被折叠的 条评论
为什么被折叠?



