2

我有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没有调用析构函数是正常的吗?解决方案是什么?

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

3 回答 3

12

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

解决办法是什么?

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

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

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

于 2013-10-03T12:06:55.543 回答
6

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

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

于 2013-10-03T12:05:38.453 回答
0

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

于 2013-10-03T13:14:46.670 回答