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

Определение 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деструктор?

3 ответа

Решение

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

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

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

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

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

auto* ptr = new some_class();

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

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

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

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

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

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

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

Конец.

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

Другие вопросы по тегам