2016-02-17 1 views
2

Так вот код:Когда программа не вызывает деструктор в C++?

#include <iostream> 

using namespace std; 

class C { 
public: 
    C() {i = 6; cout << "A:" << i << endl;} 

    C(int i0) {i = i0; cout << "B:" << i << endl;} 

    ~C() {cout << "C:" << i << endl;} 
private: 
    int i; 
}; 

int main(int argc, char* argv[]) { 
    cout << "X" << endl; 
    C *c = new C; 
    cout << "Y" << endl; 
} 

По какой-то причине выход для этого кода

X 
A:6 
Y 

И по какой-то причине деструктора (C: 6) никогда не вызывается, когда вы дойдете до конца код. Почему это? Кроме того, этот код вызывать деструктор:

#include <iostream> 

using namespace std; 

class C { 
public: 
    C() {i = 0; cout << "A:" << i << endl;} 

    C(int i0) {i = i0; cout << "B:" << i << endl;} 

    ~C() {cout << "C:" << i << endl;} 
private: 
    int i; 
}; 

int main(int argc, char* argv[]) { 
    cout << "X" << endl; 
    C c; 
    cout << "Y" << endl; 
} 
+0

Как правило, вы должны называть 'delete' для всего, что вы называете' new' on (примечание: не всегда верно, но будет выполняться в большинстве случаев) –

+0

C++ не является C#, избегать 'new' –

+1

_When do вы не называете деструктора? _ Всегда. :) – erip

ответ

10

Потому что ты забыл написать

delete c; 

Если вы просто идете в вашей программе, не удаляя переменную инстанцированный с новым вы вызвать утечку памяти.

Edit, так как вы изменяли вопрос:

Если вы пишете что-то вроде

C c; 
C c{1}; 
C c = C{1}; 

вы создаете переменную с автоматической продолжительности хранения. Он будет выходить из области действия после того, как функция объявлена ​​в выходы (или более точна: после того, как блок объявлен в выходы). В этом случае конструктор вызывается автоматически.

Если вы пишете

C* c = new C{}; 

создать указатель на (новый) C. Указатель сам имеет автоматический срок хранения, что означает с кончатся сферы, а также. Но указатель содержит только адрес объекта типа C. И этот объект удаляется только при вызове delete c;. Если вы не вызываете delete, ваша программа «забывает» адрес объекта, но не освобождает память или не уничтожает объект. Это утечка памяти.
Однако, как только ваша программа заканчивается, вся память освобождается (без вызова деструкторов), поэтому в вашем маленьком примере вы не заметите.

+0

Но есть еще один код (который я разместил вверху), где я не вызываю delete c и тот, который называется деструктором. –

+0

Я немного рассказал об этом. – Anedar

5

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

Деструктор вызывается автоматически, когда объект уничтожается, либо выйдя из области видимости для экземпляра стека, либо будучи delete d для экземпляра кучи. Поэтому тот факт, что ваш деструктор не вызван, говорит вам что-то: объект теряется или просачивается.

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

В вашем коде вы никогда не создали delete экземпляр, который вы создали.

#include <iostream> 

using namespace std; 

class C { 
public: 
    C() : m_i(6) { cout << "A:" << m_i << endl;} 

    C(int i_) : m_i(i_) { cout << "B:" << m_i << endl;} 

    ~C() {cout << "C:" << m_i << endl;} 
private: 
    int m_i; 
}; 

int main(int argc, char* argv[]) { 
    cout << "X\n"; 
    C* c = new C; 
    C stackC; 
    cout << "Y\n"; 
    delete c; 
    cout << "Z\n"; 
} 

Живая демонстрация: http://ideone.com/iuZim4

0

При использовании «новый», чтобы выделить динамическую переменную, время жизни экземпляра объекта заканчивается 1) удаление или 2) завершение процесса, или 3) сброс системы.

В вашем коде программа заканчивается перед 'delete c;' вызывается, поэтому dtor не вызывается процессом.

Любая динамическая память, используемая процессом, «исправлена», когда ОС завершает процесс. Эта ОС «Reclaiming» также не вызывает dtor.

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^