今天刷QQ,看到群里甩了张这样的表情包

很有意思,看图片可以知道是”tan90°”表情包的衍生版,那么问题来了
“调用基类指针指向的派生类的非虚的析构函数”是个什么东西?
为什么它不可能呢?
首先,我们写出代码
#include<iostream>
using namespace std;
class Base {
public:
Base() = default;
~Base() {
cout << "delete base" << endl;
}
};
class Derived :public Base {
public:
Derived() = default;
~Derived() {
cout << "delete derived" << endl;
}
};
int main() {
Base *p = new Derived();
delete p;
system("pause");
return 0;
}
运行结果:

果然没有运行派生类的析构函数
用正确的写法再写一次
#include<iostream>
using namespace std;
class Base {
public:
Base() = default;
virtual ~Base() {
cout << "delete base" << endl;
}
};
class Derived :public Base {
public:
Derived() = default;
virtual ~Derived() {
cout << "delete derived" << endl;
}
};
int main() {
Base *p = new Derived();
delete p;
system("pause");
return 0;
}
运行结果:

这样便正确了
为什么?
一旦某个函数被声明成虚函数,则在所有派生类中它都是虚函数
由于静态绑定,如果以一个基类指针指向一个派生类对象,那么经由该指针只能访问基类定义的函数
如果基类的析构函数不是虚函数,则delete一个指向派生类对象的基类指针将产生未定义的行为
也就是说,要调用基类指针指向的派生类的非虚的析构函数,只能将基类的析构函数定义为非虚的
而通过基类指针,只能访问基类定义的函数,但是基类的析构函数非虚,于是直接执行了,轮不到派生类的析构函数登场
- 基类的引用或指针调用一个虚成员函数时会执行动态绑定
在正确的写法下,通过基类指针,动态绑定到派生类的虚析构函数上,于是先执行派生类类的析构函数,然后执行基类的析构函数
参考文献
[1]《C++ Primer(第5版)》电子工业出版社——第十五章