Поведение явного вызова деструктора

Определение some_class является:

class some_class
{
// stuff

public:
~some_class()
{
delete dynamic_three;
}

private:
classA one;
classB two;
classC* dynamic_three;
}

Когда время жизни объекта заканчивается, его уничтожение: (1) вызвать его деструктор и (2) уничтожить его подобъекты в том же порядке, в котором они объявлены в определении класса (= позиция в памяти).

Но, если у меня есть что-то подобное:

auto* ptr = new some_class();

// more stuff

ptr->~some_class(); // l. X

Шаг (2) также реализован? Я имею в виду, в строке X также называются деструкторы подобъектов или выполняется только тело some_classдеструктор?

5

Решение

Когда время жизни объекта заканчивается, его уничтожение: (1) вызвать его деструктор и (2) уничтожить его подобъекты в том же порядке, в котором они объявлены в определении класса (= позиция в памяти).

и (3) выделенная память освобождается.

Шаг (2) также реализован?

Шаг (2) да, но не шаг (3).

Но если вы можете написать

auto* ptr = new some_class();

обратите внимание, что вы также можете написать

std::unique_ptr<ptr> ptr (new some_class());

который бы назвал delete для вас (конечно, используйте это, только если это соответствует вашим потребностям, но используйте это по умолчанию, если вы не уверены).

1

Другие решения

Шаг (2) также реализован?

Да, это гарантировано. Поведение является безопасным, но обратите внимание, что в вашем случае у вас нет способа безопасно восстановить память объекта, не восстанавливая его сначала с помощью размещения нового (если вы не перекрыли operator new для вашего объекта, и таким образом вы можете гарантировать, как память была выделена и использовать соответствующее освобождение).

2

Давайте сделаем тест:

class classA
{
public:
~classA() { cout << "~classA()" << endl; }
};

class classB
{
public:
~classB() { cout << "~classB()" << endl; }
};

class some_class
{
public:
~some_class() { cout << "~some_class()" << endl; }

private:
classA one;
classB two;
};

int main()
{
cout << "Start..." << endl;

auto* ptr = new some_class();

ptr->~some_class();

cout << "End." << endl;
}

Выход:

Начните…

~ Some_class ()

~ ClassB ()

~ CLASSA ()

Конец.

Так что все деструкторы называются и в обратном порядке.

2
По вопросам рекламы [email protected]