414 words
2 minutes
C++为什么析构函数是虚函数
先要澄清一点,析构函数是可以设定为虚函数,而不是必然会设定为虚函数。默认的类的析构函数不是虚函数。只有那些用到继承特性的类才需要虚析构函数。
这个问题其实只需要用一句话就可以解释,跟所有虚函数的使用情景相同,因为我们可能会用父类的指针去析构一个对象。
// a.cpp
#include <iostream>
class Base {
public:
Base() {
std::cout << "Create Base!" << std::endl;
}
virtual ~Base() {
std::cout << "Destory Base!" << std::endl;
}
};
class Derived : public Base {
public:
Derived() {
std::cout << "Create Derived!" << std::endl;
}
virtual ~Derived() {
std::cout << "Destory Derived!" << std::endl;
}
};
int main() {
auto a = new Base();
auto b = new Derived();
delete a;
delete b;
return 0;
}
编译运行一下:
$g++ a.cpp && ./a.out
Create Base!
Create Base!
Create Derived!
Destory Base!
Destory Derived!
Destory Base!
这个当然我们一点也不意外。
现在,做一点改动,把源代码第26行改成:
Base* b = new Derived();
再次编译运行:
$g++ a.cpp && ./a.out
Create Base!
Create Base!
Create Derived!
Destory Base!
Destory Derived!
Destory Base!
注意这里的b
是一个Base
的指针,它正确地找到了所管理的类的析构函数。
接下来,我们取消Base
和Derived
的析构函数virtual
,再次编译运行:
$g++ a.cpp && ./a.out
Create Base!
Create Base!
Create Derived!
Destory Base!
Destory Base!
这个时候,就没有Destory Derived!
的信息了,这说明delete b
调用的是父类的析构函数。
在这种情况下,非常容易有内存泄漏的问题,因此如果类需要继承,那么析构函数就需要虚函数。(父类的析构函数有virtual标记即可)。
C++为什么析构函数是虚函数
https://ziyue.cafe/posts/cpp-why-destructor-is-virtual/