从基类指针(可能)破坏对象时,需要虚拟析构函数。
考虑一个没有动态内存的程序,这在嵌入式系统中很常见。在这里,使用new
或delete
会触发链接器错误,因为未实现所需的基础分配器。因此,开发人员仅使用静态分配的对象(在bss / data部分中)或自动分配的对象(通常在堆栈上)。
在这样的系统中,是否确实需要虚拟析构函数? (假设没有人感到无聊,并在某个指针上手动调用了析构函数。)
在我看来,静态和自动分配总会始终调用正确的析构函数。我想念什么吗?有没有极端情况?静态对象池与unique_ptr和自定义删除器一起使用怎么办?
答案 0 :(得分:4)
假设没有人感到无聊,并在某个指针上手动调用了析构函数。
我认为您已经过快地排除了这种可能性。禁止动态分配的嵌入式/内存受限系统仍然可以创建具有动态存储 duration 的对象。观察:
alignas(T) char memory[sizeof(T)];
T *p = new(memory) T; //Does not call global `new` allocator.
/*do stuff with `p`*/
p->~T();
没有理由禁止这样做。实际上,类型擦除的某些实现依靠小对象优化来实现这一点。小对象的std::any
实现可以完全使用std::any
对象本身中的内存来构造派生类。但是它仍然需要调用该类型的析构函数,通常是通过基类指针进行的。 any
的某些实现当然不要使用继承,但是我的总体意思是明确禁止手动调用析构函数会很奇怪。