删除 void 指针时不调用析构函数

Destructor not invoked when deleting void pointer

本文关键字:调用 析构函数 void 指针 删除      更新时间:2023-10-16

我有 3 个类

class A
{
    A();
    virtual ~A();
}
class B : public A
{
    B();
    ~B();
}
class C
{
    void *obj;
    C() : obj(nullptr) {}
    ~C() { if (obj) delete obj; }
}

当我使用类 C 作为类 A 的任何子项的容器并尝试删除C实例时。 A,析构函数B不被初始化是正常的吗?什么是解决方案?

C* instance = new C();
instance.obj = new B();
//Magic
delete instance; // A and B destructor is not called

删除指向不兼容类型(包括void)的指针会给出未定义的行为。

解决方案是什么?

  • 使用正确的类型:使用 new 指定的类型,或者基类(如果具有虚拟析构函数);或
  • 使用 std::shared_ptr<void> ,从 std::shared_ptr<correct_type> 初始化:它的删除器将做正确的事情。

在这种情况下,看起来您可以简单地存储A*而不是void*,因为您说它应该是"任何 A 类子项的容器"。

顺便说一下,在删除指针之前,无需检查指针是否为 null。

你删除了一个void*,所以delete不知道它是一个B*所以不能调用析构函数。如果要在删除时调用析构函数,则必须使用类指针。

例如,是所有可能是 C 的类obj扩展 A,然后使用 A*

是的,删除需要特定的类型。