2013-02-21 7 views
6

Oto mój strukturę AW C++, jak napisać destruktor do zwalniania pamięci wskaźnika do struktury?

struct A { 
    int a1; 
    int a2; 
    ~A() { } 
}; 

B jest inna konstrukcja, która zawiera wskaźnik do

struct B { 
    B(int b, A* a) 
     : b1(b), ptr2A(a) 
    {} 
    int b1; 
    A* ptr2A; 

    ~B() { 
     delete b1; 
     // traverse each element pointed to by A, delete them <---- 
    } 
}; 

Później używam poniżej kod

int bb1; 
vector <A*> aa1; 
// do some stuff 
B *ptrB = new B(bb1, aa1); 

muszę usunąć/free wszystko pamięć wskazywana przez ptrB. Dlatego muszę napisać poprawny destruktor wewnątrz struktury B. Jak przejść przez każdy element wskazany przez A i usunąć je?

+2

Potrzebujesz książki w języku C++. Próbujesz łączyć ze sobą różne rzeczy z 'C' i próbować" usuwać "automatyczne zmienne. Co więcej, w 'A' nie ma nic do przejrzenia - po prostu' usuń ptr2A'. – Yuushi

+1

Dlaczego usuwasz b1? – StarPinkER

+0

możliwy duplikat [Jak pisać destruktor, gdy mam wskaźniki w klasie?] (Http://stackoverflow.com/questions/5317735/how-to-write-destructor-when-i-hpoint-pointers-in-class) – jogojapan

Odpowiedz

12

Jeśli używasz kompilatora C++ 11, po prostu użyj std :: shared_ptr i nie musisz się martwić usuwaniem. Dzieje się tak, ponieważ shared_ptr jest "inteligentnym" wskaźnikiem, który automatycznie usuwa to, na co wskazuje.

#include <memory> 
struct B 
{ 
    int b1; 
    std::shared_ptr<A> ptr2A; 
    B(int b, std::shared_ptr<A> a):b1(b),ptr2A(a)({} 
    ~B(){} //look ma! no deletes! 
}; 

pomocą udostępnionego wskaźnik ilekroć przydzielić coś:

#include<memory> 
... 
{ 
    .... 
    std::shared_ptr<B> ptrB(new B(bb1, aa1)); 
    //Here is another, more readable way of doing the same thing: 
    //auto ptrB = std::make_shared<B>(bb1,aa1); 
    ... 
} 
//no memory leaks here, because B is automatically destroyed 

Here's more info na temat inteligentnych wskaźników.

Należy również wspomnieć, że jeśli nie masz kompilatora C++ 11, możesz uzyskać współdzielone wskaźniki od BOOST library.

+0

Przepraszam. Długo pisałem. Dodałem szczegóły do ​​pytania.Używam nowego operatora później – user13107

+0

Dzięki! Więc znaczysz, że muszę po prostu "usunąć ptrB" i wszystko będzie załatwione? – user13107

+0

Dopóki używasz inteligentnych wskaźników, nie musisz robić usunięć. Istnieją różne typy inteligentnych wskaźników, ale na razie zacznij od shared_ptr. – Carl

4

Masz tylko jedną wskazówkę na A. Więc trzeba tylko usunąć że:

~B() { 
    delete ptr2A; 
} 

pamiętać, że nie delete b1 może, ponieważ jest to zwykły int! (Pamięć podjęta przez zmienne struktury, takie jak b1 a wskaźnik ptr2A samego (nie to, co wskazuje) są zniszczone automatycznie wraz ze wszystkimi instancjami tej struktury.)

+0

Przepraszamy. Długo pisałem. Dodałem szczegóły do ​​pytania. Używam nowego operatora później – user13107

5

tylko trzeba delete obiekty przydzielone przez new. W takim przypadku nie ma potrzeby usuwania b1, ponieważ nie zostało ono przydzielone dynamicznie. Co więcej, jeśli nie zainicjowałeś ptr2a z pamięcią dynamiczną, usunięcie go jest niezdefiniowanym zachowaniem.

Nie trzeba się więc martwić usuwaniem danych z A s, ponieważ zostaną one zniszczone z pamięci w instancji klasy.

+0

Niestety. Długo pisałem. Dodałem szczegóły do ​​pytania. Używam nowego operatora później. – user13107

+0

Wszystko, co musisz zrobić, to użyć 'delete ptrB' kiedy skończysz używając pamięci, do której on prowadzi. Nie rób tego wewnątrz klasy, zrób to w środku, gdzie ją zdefiniowałeś. – 0x499602D2

+0

Ah. Miałem wrażenie, że kod 'delete ptrB' wywoła destruktor B. Musimy to zrobić (uwalniając pamięć wskazaną przez' aa1') wewnątrz destruktora B. – user13107

Powiązane problemy