Удаление объекта

Во-первых, когда Вы хотите освободить память, присвоенную объекту в C++, какой предпочтен? Явно звонящий деструктор или использование удаляют?

Object* object = new Object(...);
...

delete object;

ИЛИ

object->~Object();

Во-вторых, оператор delete называет деструктор неявно?

5
задан Unihedron 10 August 2014 в 11:32
поделиться

9 ответов

delete неявно вызывает деструктор, вам не нужно (точнее: не следует) вызывать его напрямую.

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

Чтобы освободить память объекта, выделенную на куче, вы должны вызвать delete.

Когда вы пишете свой собственный класс, C++ предоставит деструктор по умолчанию для освобождения памяти, выделенной компонентными объектами (такими как QString, который является членом вашего класса), но если вы явно выделяете память (или другие ресурсы) в своем конструкторе, не забудьте предоставить деструктор, который явно освободит эти ресурсы.

Еще одно общее правило, касающееся ваших собственных классов: Если вы помечаете какие-либо методы virtual, ваш деструктор также должен быть virtual (даже если вы полагаетесь на деструктор по умолчанию), чтобы для всех классов, производных от вашего, вызывался правильный деструктор.

13
ответ дан 18 December 2019 в 05:19
поделиться

Удалить предпочтительнее. Простой вызов деструктора не освобождает память, выделенную новым.

4
ответ дан 18 December 2019 в 05:19
поделиться

Я не предпочитаю ни то, ни другое.

Явный вызов деструктора требуется очень и очень редко, только когда вы отделяете выделение памяти от времени существования объекта. Он может вам понадобиться, если вы реализуете собственный контейнерный класс.

Явное удаление потенциально является допустимым способом уничтожения объекта, динамически созданного с помощью выражения new , но оно не должно быть необходимым в большинстве программных кодов, поскольку оно сигнализирует о месте, где Могут возникнуть потенциальные несоответствия между новыми и удаляемыми, а также области с потенциальными проблемами безопасности, связанными с исключениями.

Если время жизни объекта ограничено блоком, обычно предпочтительнее использовать локальную переменную, поскольку накладные расходы на выделение памяти обычно ниже, и объект будет автоматически очищен правильно, однако выход из блока будет завершен.

{
    // ...
    Object object( ... );

} // object destructor run, however this block is exited.

Если есть какая-то причина, по которой в этом нет необходимости (например, объект имеет чрезмерный статический размер) или его время жизни не может быть сопоставлено с определенной областью видимости, то обычно следует использовать какой-то интеллектуальный указатель для управления время жизни объектов. Самый простой интеллектуальный указатель, доступный в стандартном C ++, - это std :: auto_ptr , который может использоваться для динамически выделяемых объектов с блочной областью видимости, но имеет «удивительное» поведение при копировании и назначении. Что-то вроде tr1 :: shared_ptr (или boost :: shared_ptr ) является распространенной альтернативой, когда требуется совместное владение.

{
    std::auto_ptr<Object> object(new Object(...));
    // ...
} // *object destructor run, however this block is exited.
7
ответ дан 18 December 2019 в 05:19
поделиться

Используйте удалить . Он вызывает деструктор объектов , а затем освобождает выделенную память.

Кроме того, это не деконструктор, а деструктор.

4
ответ дан 18 December 2019 в 05:19
поделиться

Вызов delete вызовет деструктор, а затем освободит память.

При явном вызове деструктора будет вызван только деструктор, но не освобождена память.

Поэтому почти всегда следует вызывать delete: за исключением случаев, когда вы хотите вызвать деструктор без освобождения памяти, например, потому что вы создали объект с помощью размещения new.

4
ответ дан 18 December 2019 в 05:19
поделиться

Никогда не вызывайте деструктор самостоятельно. delete позвонит вам

2
ответ дан 18 December 2019 в 05:19
поделиться

Обычно вы никогда не хотите явно вызывать деструктор. Просто используйте delete.

4
ответ дан 18 December 2019 в 05:19
поделиться

Нужно еще кое-что учесть:

поскольку delete вызывает внутренний деструктор, будет ошибкой сделать и то, и другое, т.е. вызвать деструктор, а затем delete. Поэтому следующий код:

Foo* px = new Foo;
// …
px->~Foo();
delete px;

приведет к неприятной ошибке. В зависимости от действий, выполняемых в деструкторе, это может оставаться незамеченным довольно долгое время, поскольку компилятор фактически разрешает такой код. Это может привести к тонким, трудно обнаруживаемым ошибкам.

2
ответ дан 18 December 2019 в 05:19
поделиться

Вы должны использовать delete

http://www.parashift.com/c++-faq-lite/dtors.html

1
ответ дан 18 December 2019 в 05:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: