当您知道在这种特定情况下析构函数是 noop 时,标准是否要求调用非平凡的析构函数?
如果不调用析构函数,代码是否可能被编译器破坏?
用例是一个包含动态分配指针的类。默认情况下,这个指针是new
在构造函数中获得的。此类还可以从分配器中获取其动态分配的指针。该类跟踪它是如何获得其指针的,delete
如果指针是由分配器获得的,则在析构函数中调用,new
如果它是由分配器获得的,则什么都没有,因为分配器将释放内存。存储在动态内存中的数据只是普通类型,因此不需要调用它们的析构函数。
所以问题是,如果我知道它通过分配器获得了它的指针,那么我是否还需要在类上调用析构函数,所以析构函数是一个 noop ?
这是一个最小的简化示例,与问题没有直接关系的所有内容都已删除。
struct Allocator {
void* ptr = nullptr;
void* Allocate(size_t size) {
ptr = malloc(size);
return ptr;
}
~Allocator() { // allocator will cleanup
if (ptr)
free(ptr);
}
};
struct C {
int* ptr;
bool need_cleanup;
C() {
ptr = new int[10];
need_cleanup = true;
}
C(Allocator& A) {
ptr = (int*)A.Allocate(10 * sizeof(int));
need_cleanup = false;
}
~C() { // non-triviall because user-defined.
if (need_cleanup)
delete[] ptr;
// noop if need_cleanup is false.
}
};
int main()
{
Allocator A;
alignas(C) char buffer[sizeof(C)];
C* c = new(buffer) C(A);
/// is it required to call c->~C();
}