2013-07-09 3 views
1

У меня есть следующий код и, как я знал, в конце программы, которая использует конструкторы классов, если определенные объекты были созданы, они уничтожены. Судя по тому, что в конце выполнения я должен У меня были некоторые «~ B()» и «~ D()», напечатанные в определенном порядке, но этого не происходит, когда я запускаю код. Почему?Конструкторы и деструкторы

#include<iostream> 
#include<stdlib.h> 
using namespace std; 

class B{ 
public: 
    B(){cout<<"B()";} 
    virtual void print(){cout<<"b";} 
    ~B(){cout<<"~B()";} 
}; 

class D:public B{ 
public: 
    D(){cout<<"D()";} 
    void print(){B::print() 
    ;cout<<"d";} 
    ~D(){cout<<"~D()";} 
    }; 

void testI(){ 
    B* b[]={new B(),new D()}; 
    b[1]->print(); 
    B&c=*b[1]; 
    c.print(); 
} 



int main(){ 
    testI(); 
return 0; 
} 
+1

Где 'delete' (а' B' требует 'virtual' destructor)? – hmjd

+1

Потому что вы создаете объекты с 'new' и не вызываете' delete'. Попробуйте 'int main() {B b; } ' – juanchopanza

ответ

3

Вы создаете свои объекты с new, это означает, что они выделяются в куче, а не стек, и там Фор это до вас, чтобы удалить их.

B * b = new B(); 

Позже ..

delete b; 

Edit:

Для массивов используют:

delete[] b; //if b is a pointer to an array of B's 
+0

Я забыл о куче. Спасибо. – Matt

2

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

читать о новых и удалять здесь: http://www.cplusplus.com/reference/new/

0

Вы используете новый выделить динамическую память без удаления объектов. Хотя вы можете решить эту проблему, добавив инструкцию delete, так как ваш код становится более сложным, вы обнаружите, что управление ручной памятью может стать громоздким и подверженным ошибкам.

Вы будете намного лучше использовать классы управления памятью, такие как std::unique_ptr и std::shared_ptr, и используя классы контейнеров, такие как std::vector.

void testI() 
{ 
    std::vector<std::shared_ptr<B>> b = {std::make_shared<B>(), std::make_shared<D>()}; 
    b[1]->print(); 
    B& c= *b[1]; 
    c.print(); 
} //b is destroyed here 
0

В норме:

3.6.1.5 - Оператор возврата в основном имеет эффект оставляя основную функцию (разрушающую любые объекты с автоматической продолжительностью хранения)

Итак, во время вашей программы вы создаете несколько переменных. При возврате из основной части уничтожаются только те, у которых время автоматического хранения. Те, у которых динамическая длительность хранения данных, отсутствуют. Для ваших переменных с динамической продолжительностью хранения вы должны явно вызвать delete.

Вот небольшой пример. Поместите контрольную точку в деструктор и проверьте значение m_name.

#include <iostream> 
#include <string> 

class A 
{ 
public: 
    A(const std::string &name):m_name(name){} 

    ~A() 
    { 
     std::cout<<"deleting "<<m_name<<std::endl; 
    } 

private: 
    std::string m_name; 
}; 

A a("Variable at namespace scope"); 

int main() 
{ 
    A a0("Automatic storage"); 
    A *a1 = new A("Dynamic storage 1"); 
    A *a2 = new A("Dynamic storage 2"); 
    delete a2; 
    static A a3("Static storage"); 

    return 0; 
} 
+0

Когда вы вернетесь из 'main' (или вызовите exit), объекты со статическим временем жизни также будут разрушены. –

+0

Это была не цель здесь, но вы правы, лучше добавить тоже. Благодарю. – Korchkidu

+0

@JamesKanze: Edit done. Надеюсь, это было то, что вы имели в виду. – Korchkidu