1、析构虚函数为什么要为虚函数
#include <iostream>
using namespace std;
class Base {
public:
~Base() { cout << "Base destructor\n"; }
};
class Derived : public Base {
public:
~Derived() { cout << "Derived destructor\n"; }
};
int main() {
Base* p = new Derived();
delete p; // ⚠️ 只调用 Base 析构函数
return 0;
}
可以看到,派生类 Derived 的析构函数没有被调用。
这会造成:
-
派生类部分(如成员对象、动态分配资源)没有被释放;
-
从而出现内存泄漏、资源未释放的严重问题。
-
正确的做法:把析构函数声明为虚函数
-
#include <iostream>
using namespace std;class Base {
public:
virtual ~Base() { cout << "Base destructor\n"; }
};class Derived : public Base {
public:
~Derived() override { cout << "Derived destructor\n"; }
};int main() {
Base* p = new Derived();
delete p; // ✅ 调用 Derived 和 Base 析构函数
return 0;
}在 C++ 中,多态依赖 虚函数表(vtable)。
-
当类中有虚函数时,编译器会为对象维护一个 虚函数表指针(vptr)。
-
删除对象时,如果析构函数是虚函数,
delete操作会根据实际对象类型调用正确的析构函数链。
虚析构函数保证了“通过基类指针删除派生类对象”时,调用真正的析构过程。
| 场景 | 是否需要虚析构函数 | 原因 |
|---|---|---|
| 类不打算作为基类 | ❌ 不需要 | 没有多态删除风险 |
| 类作为基类使用 | ✅ 必须有 | 确保派生类析构正确调用 |
| 类中已有虚函数 | ✅ 推荐 | 通常一起定义析构为虚 |
| 类作为接口(纯虚类) | ✅ 一定要 | 防止通过接口指针 delete 派生对象 |
当类被用作基类并会通过基类指针删除派生对象时,析构函数必须是虚函数,否则会导致资源泄漏或未定义行为。
1)进程和线程的区别
2)进程间通信的方式有哪些?
说一下信号量是怎么使用的?
3)A进程中有一个变量a,B进程,A进程可以把a的地址值发给B吗?B进程收到A的地址可以修改A中的地址吗?只能读取不能修改吗?
4)计算机中的数据存储是怎么分布的?
5)类中一个成员,是在哪个存储区?
6)找不到符号是发生在哪个阶段?
7)除了这些语言还有什么其他技能?
英语,还有列?

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



