2012-05-24 13 views
8

Jaki jest cel wyznaczania zakresu? do mojego zrozumienia, wskaźnik zakresu zajmuje się pamięcią wewnątrz bloku kodu. Jeśli chcę zadeklarować zmienną w bloku, mogę po prostu zadeklarować ją na stosie i nie martwić się o czyszczenie.Dlaczego wskaźniki zakresu w zwiększeniu

+0

http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm#Handle/Body –

Odpowiedz

1

Chodzi o to, że można utworzyć i wyczyścić wskaźnik w określonym zakresie leksykalnym. Może to być przydatne w różnych sytuacjach i zapewnia, że ​​nie masz żadnych wycieków pamięci, zapominając o delete, jeśli używałbyś jawnie, co nie jest zalecane, jako new.

Należy pamiętać, że boost::scoped_ptr jest bez możliwości kopiowania , który nie może być kopiowany, a więc jest właścicielem całego zasobu przez cały okres jego istnienia. Dzięki temu jest bezpieczniejsze niż boost::shared_ptr, ponieważ unika kopiowania zasobu lub przypadkowego udostępniania go.

{ //Some Scope 

    boost::scoped_ptr<int> i_ptr; 
    // do something with pointer 

} // leave scope, pointer is cleaned up 
4

Nie, jeśli ma dynamiczny rozmiar lub typ. Ponadto, wskaźniki zakresu mogą być zamieniane, a w C++ 11 unique_ptr mogą być przenoszone, więc nie są ściśle określone.

+1

wyjątkiem, że”główny powód do użyj 'scoped_ptr' zamiast' auto_ptr', aby czytelnicy twojego kodu wiedzieli, że masz zamiar "pozyskiwania zasobów jest inicjalizacją", który ma być zastosowany tylko dla bieżącego zakresu i nie ma zamiaru przenosić własności "... wydaje się być' zamiennikiem ' 'nie jest zamierzonym użytkowaniem. –

+0

@BenVoigt: Ale jest dostarczony i może być używany. – Puppy

+2

Oto [stary wątek] (http://lists.boost.org/Archives/boost/2002/09/36359.php) omawiający, dlaczego 'swap' stał się wymaganiem (w zasadzie więc' scoped_ptr' może być używany jako członek klasy do kopiowania). –

0

Zwykle stosy wątków mają ograniczenia pamięci (patrz wątek stosu).

także czasami wskaźnik mógł zostać przekazany do ciebie z zewnątrz i musi zostać usunięty w tym zakresie (np. Jeśli zostanie zgłoszony wyjątek, żadne wywołanie usuwania poniżej tego wiersza nie zostanie wykonane). Więc trzeba jakoś auto-magicznie czyszczenia wskaźnik

void foo(Object*obj) 
{ 
    //this will ensure that object gets cleaned up even if doFoo() throws an exception 
    boost::scoped_ptr<Object> objCleaner(obj); 
    obj->doFoo(); 
} 
+0

Mogę zadeklarować wskaźnik na stosie i będzie on automatycznie czyszczony, gdy funkcja wykracza poza zakres, albo z powodzeniem, albo z powodu wyjątku. Poprawny? – Jimm

+0

{X * x = & someObj; } nie spowoduje to usunięcia wskaźnika x, gdy wykracza poza zakres. someObj zostanie usunięte, gdy wykracza poza zakres. {X * y = nowy X();} ten typ kodu będzie wymagał scoped ptr do automatycznego czyszczenia – mohaps

2

przeciwieństwie do danych na stosie, scoped_ptr ma reset() członek - innymi słowy, można skonstruować/destruct do syta. Dzięki temu można użyć wskaźnika zerowego (technicznie operator unspecified-bool-type) jako flagi wskazującej, czy w danym momencie istnieje obiekt zbudowany, czy też nie. Pozwala także na sekwencję konstrukcji/zniszczenia niezależnie od zakresu zmiennej, jeśli jest to potrzebne.

Ponadto, możesz zadeklarować scoped_ptr jako element klasy, a nie tylko jako zmienną stosu. docs sugeruje użycie scoped_ptr do implementacji idiomu uchwyt/ciało (aby ukryć szczegóły implementacji klasy).

Wreszcie, aby rozwinąć punkt DeadMG za „Nie, jeśli to dynamicznej typu” można użyć scoped_ptr wdrożyć polymorphic operacji:

{ 
scoped_ptr<Base> a(mode ? new DerivedA : new DerivedB); 
a->polymorphic_function(); 
} 

To naprawdę nie jest możliwe, aby to zrobić z prosty stack- na podstawie przydziału.


patrz także tutaj: C++0x unique_ptr replaces scoped_ptr taking ownership?

+0

'boost :: wariant '. :) – GManNickG

+0

@GManNickG: Nie sądzę, aby boost :: variant był dobrym zamiennikiem polimorfizmu przez scoped_ptr - co ciekawe. Dzięki! – nobar

+0

Dlaczego tak nie sądzisz? – GManNickG