Является ли эта программа хорошо определенной, а если нет, то почему именно?Может ли деструктор быть рекурсивным?
#include <iostream>
#include <new>
struct X {
int cnt;
X (int i) : cnt(i) {}
~X() {
std::cout << "destructor called, cnt=" << cnt << std::endl;
if (cnt-- > 0)
this->X::~X(); // explicit recursive call to dtor
}
};
int main()
{
char* buf = new char[sizeof(X)];
X* p = new(buf) X(7);
p->X::~X(); // explicit call to dtor
delete[] buf;
}
Мои рассуждения: хотя invoking a destructor twice is undefined behavior, на 12,4/14, что он говорит именно это:
поведение не определено, если деструктор вызывается для объекта , время жизни закончилась
Это не запрещает рекурсивные звонки. Хотя деструктор для объекта выполняется, время жизни объекта еще не закончено, поэтому не UB снова вызывает деструктор. С другой стороны, 12,4/6 говорит:
После выполнения тела [...] деструктора для класса X называет деструкторов для прямых членов иксов, деструкторов для прямого основания Х классов [ ...]
, что означает, что после возвращения из рекурсивного вызова деструктора, все деструкторы класса членов и базовых будут призваны, и призывая их снова при возвращении на прежний уровень рекурсии будет UB , Следовательно, класс без базовых и только элементов POD может иметь рекурсивный деструктор без UB. Я прав?
Это действительно странно, почему вы когда-нибудь хотите назвать рекурсивный деструктор? – Andrey
Достойный вопрос для дяди Боба. –
Почему, черт возьми, ты когда-нибудь захочешь это сделать? – Puppy