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

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

5 голосов
/ 03 июня 2010

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

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

delete object;

OR

object->~Object();

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

Ответы [ 10 ]

13 голосов
/ 03 июня 2010

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

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

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

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

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

7 голосов
/ 03 июня 2010

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

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

Явный delete потенциально является законным способом уничтожения объекта, динамически создаваемого с помощью выражения 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.
4 голосов
/ 03 июня 2010

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

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

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

4 голосов
/ 03 июня 2010

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

4 голосов
/ 03 июня 2010

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

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

4 голосов
/ 03 июня 2010

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

2 голосов
/ 03 июня 2010

Что еще нужно учитывать:

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

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

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

2 голосов
/ 03 июня 2010

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

1 голос
/ 03 июня 2010

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

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

0 голосов
/ 05 мая 2014

Когда вы используете динамическое выделение памяти для создания объекта в то время, вы можете использовать оператор удаления, чтобы уничтожить / удалить объект, но когда вы не используете DMA в то время, пытаясь удалить объект с помощью оператора удаления, выдает ошибку.Одним из способов справиться с этой ситуацией является явное написание собственного деструктора и вызов деструктора с использованием объекта для его уничтожения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...