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

时间:2013-10-03 11:58:53

标签: c++ pointers containers destruction

我有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实例。 AB析构函数不是正常的吗?什么是solutuon?

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

3 个答案:

答案 0 :(得分:12)

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

  

解决方案是什么?

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

在这种情况下,看起来您只需存储A*而不是void*,因为您说它应该是“类A的任何子容器”。

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

答案 1 :(得分:6)

您删除了void*,因此delete不知道它是B*,因此无法调用析构函数。如果希望在删除时调用析构函数,则必须使用类指针。

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

答案 2 :(得分:0)

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