требуется ли в стандарте вызывать нетривиальный деструктор, когда вы знаете, что в данном конкретном случае деструктор является 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();
}