2012-09-30 13 views
6

Spójrz na ten kod:Dlaczego C++ std :: list :: clear() nie wywołuje destruktorów?

class test 
{ 
    public: 
     test() { cout << "Constructor" << endl; }; 
     virtual ~test() { cout << "Destructor" << endl; }; 
}; 

int main(int argc, char* argv[]) 
{ 
    test* t = new test(); 
    delete(t); 
    list<test*> l; 
    l.push_back(DNEW test()); 
    cout << l.size() << endl; 
    l.clear(); 
    cout << l.size() << endl; 
} 

A potem spojrzeć na tego wyjścia:

Constructor 
    Destructor 
    Contructor 
    1 
    0 

Pytanie brzmi: Dlaczego destruktor elementu listy nie zawinął l.clear()?

Odpowiedz

12

Twoja lista zawiera wskaźniki. Wskaźniki nie mają destruktorów. Jeśli chcesz wywołać destruktor, powinieneś zamiast tego spróbować list<test>.

+0

Fajnie, tak właśnie myślałem, ale chciałem to potwierdzić. – danikaze

+0

Lub użyj Boost.PointerContainer's ['ptr_list'] (http://www.boost.org/doc/libs/release/libs/ptr_container/doc/ptr_list.html). –

+1

Tak, używam SmartPointers dla większości rzeczy, ale czasami surowe wskaźniki są lepsze. Chodzi o to, że myślałem, że jeśli mam wskaźnik p, to usunięto (p) ... ale wiedząc, że teraz jest w porządku. Uwolnię surowe wskazówki. – danikaze

3

Lepszą alternatywą dla zwalniania wskaźników za pomocą delete, lub używania czegoś, co je usuwa (takiego jak inteligentne wskaźniki lub pojemniki wskaźnika), jest po prostu tworzenie obiektów bezpośrednio na stosie.

Powinieneś woli test t; od test * t = new test(); Bardzo rzadko chcesz zajmować się dowolnym wskaźnikiem, który jest właścicielem zasobu, inteligentny lub w inny sposób.

Jeśli miałbyś używać std::list "prawdziwych" elementów, zamiast wskazywać na elementy, nie miałbyś tego problemu.

Powiązane problemy