gpt4 book ai didi

c++ - 当它是 noop 时是否需要调用一个非平凡的析构函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:16:59 25 4
gpt4 key购买 nike

当您知道在这种特定情况下析构函数是 noop 时,标准是否要求调用非平凡的析构函数?

如果不调用析构函数,代码是否可能被编译器破坏?

用例是一个包含动态分配指针的类。默认情况下,此指针由构造函数中的 new 获取。此类还可以从分配器获取其动态分配的指针。该类跟踪它如何获得其指针并在析构函数中调用 delete 如果指针是由 new 获得的,如果它是由分配器获得的则什么都不调用,因为分配器将释放内存。存储在动态内存中的数据只是普通类型,因此不需要调用它们的析构函数。

所以问题是,如果我知道它是通过分配器获得它的指针的,那么我还需要调用类的析构函数吗?

这是一个最小的简化示例,所有与问题不直接相关的内容都已删除。

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();
}

最佳答案

没有。

For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression ([expr.delete]) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

[basic.life]

您不依赖于 ~C 的任何副作用,因此您没有未定义的行为。

注意您可能应该放置 new[] 您的 A.Allocateint[10]

C(Allocator& A) {
ptr = new (A.Allocate(10 * sizeof(int))) int[10];
need_cleanup = false;
}

关于c++ - 当它是 noop 时是否需要调用一个非平凡的析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56559504/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com