是否可以在不知道类型的情况下调用析构函数?

时间:2012-04-18 23:47:29

标签: c++ memory-management

在不使用delete的情况下,是否可以在不知道类类型的情况下调用对象的析构函数?我问,因为我正在研究一个分配器(为了好玩/练习)而我正在使用malloc / placement new来构造对象,但是当我去破坏对象时,我很好奇有一种方法可以在不知道类型的情况下这样做。如果不可能,为什么不呢?它是唯一的方法是我在示例代码中显示的方式(已注释掉)?

#include <stdio.h>
#include <new>

void* SomeAllocationFunction(size_t size) {
    return malloc(size);
}

class SomeClass{
public:
    SomeClass() {
        printf("Constructed\n");
    }

    ~SomeClass() {
        printf("Destructed\n");
    }
};

int main(void){
    void* mem = SomeAllocationFunction(sizeof(SomeClass));
    SomeClass* t = new(mem)SomeClass;

    free(t);
    //t->~SomeClass(); // This will call the destructor, is it possible to do this without knowing the class?

    return 0;
}

(我知道我可以打电话给删除,但请暂时忽略它。)

3 个答案:

答案 0 :(得分:2)

不,你不能在不知道类的情况下调用析构函数,因为编译器不知道要调用哪个析构函数。你可以:

  • 使所有对象继承自具有虚拟析构函数的某个基础对象,并使用该基础对象指针而不是空指针
  • 使用模板
  • 让分配器本身不管理构造函数/析构函数的调用

答案 1 :(得分:2)

在无类型的内存上调用析构函数比调用没有类型的构造函数(即:placement new)更有可能。构造函数和析构函数都是对象的一部分,编译器需要一个类型来知道要调用的内容。

答案 2 :(得分:2)

不,如果不知道类型(或知道具有虚拟析构函数的对象基类型之一),就不可能。

通常来说,自定义分配器既不构造也不破坏对象,尽管有些分配器围绕分配器进行模板化包装,执行新的或直接的析构函数调用。

(从技术上讲,你可以将每个分配一个最终调用该类型析构函数的函数指针关联起来。但这是相当粗略的,我不推荐它。)