一般虚函数用在多态中,进行派生类对基类函数的重写。一般虚函数是没有函数体的,只是一个声明。但是在析构函数中是特别的,因为基类和子类需要释放不同的内存
c++中如果基类指针指向的是派生类时,如果派生类的析构函数不是虚函数,那么就会导致程序在delete 对应指针时,只会走基类的析构函数而不会走派生类的虚构函数
结果如下
#include<iostream>
#include<cstring>
using namespace std;
class Father{
public:
Father()
{
cout<<"这是父类的构造函数"<<endl;
}
~Father()
{
cout<<"这是父类的析构函数"<<endl;
}
void test(){
cout <<"Father"<<endl;
}
};
class Son :public Father{
public:
Son()
{
cout<<"这是子类的构造函数"<<endl;
}
~Son()
{
cout<<"这是子类的析构函数"<<endl;
}
void test()
{
cout << "Son"<<endl;
}
};
int main()
{
Father *A = new Son();
A->test();
delete A;
return 0;
}
结果如下:
?可以知道构造函数运行了基类和派生类,但是在delete时虚构函数只执行了基类的析构函数,这样派生类中的需要释放内存的地方没有被释放,可能导致内存泄漏的安全问题
写成虚函数的情况:
#include<iostream>
#include<cstring>
using namespace std;
class Father{
public:
Father()
{
cout<<"这是父类的构造函数"<<endl;
}
virtual ~Father()
{
cout<<"这是父类的析构函数"<<endl;
}
virtual void test(){
cout <<"Father"<<endl;
}
};
class Son :public Father{
public:
Son()
{
cout<<"这是子类的构造函数"<<endl;
}
~Son()
{
cout<<"这是子类的析构函数"<<endl;
}
void test()
{
cout << "Son"<<endl;
}
};
int main()
{
Father *A = new Son();
A->test();
delete A;
return 0;
}
运行结果如下:
?从结果可以得知,普通的成员函数写成虚函数只会执行派生类重写的内容,但是析构函数会先执行派生类的析构函数再执行基类的析构函数,防止内存泄漏
|