2009-03-07 16 views
43

Mam wiele obiektów boost::shared_ptr<MyClass> iw pewnym momencie celowo chcę delete niektóre z nich, aby zwolnić trochę pamięci. (W tym momencie wiem, że nigdy nie będę już potrzebował wskazywanych obiektów MyClass). Jak mogę to zrobić?Jak celowo usunąć boost :: shared_ptr?

Domyślam się, że nie można po prostu zadzwonić pod numer delete() za pomocą surowego wskaźnika, który otrzymałem z get().

Widziałem funkcją get_deleter(shared_ptr<T> const & p) w boost::shared_ptr, ale nie jestem pewien, jak go używać, a także mówi eksperymentalny tuż obok niego. (Myślę, że mam Boost 1.38.)

Może wystarczy przypisać nowy pusty boost::shared_ptr do zmiennej? To powinno wyrzucić starą wartość i ją usunąć.

+15

NOOOOO: Nie wywołuj delete po wywołaniu, aby uzyskać(). Inteligentny wskaźnik nadal ma kopię i wywoła ją, gdy zwalnia obiekt. –

Odpowiedz

80

Wystarczy zrobić

ptr.reset(); 

Zobacz shared_ptr manual. Jest to odpowiednik

shared_ptr<T>().swap(ptr) 

zadzwonić reset na każdym inteligentne wskaźnik, który nie powinien odwoływać się do obiektu już. Ostatni taki reset (lub jakakolwiek inna czynność, która spowoduje, że licznik referencyjny spadnie do zera, faktycznie) spowoduje, że obiekt zostanie zwolniony automatycznie przy użyciu deletera.

Może jesteś zainteresowany Smart Pointer Programming Techniques. Ma wpis o numerze: delayed deallocation.

8

Sensem boost::shared_ptr<T> jest to, że obiekt wskazywany zostaną usunięte dokładnie w momencie, gdy nie shared_ptr<T> s punkt na niej - to znaczy, kiedy ostatni shared_ptr<T> wskazując na tego obiektu wykracza poza zakres lub zostanie przeniesiony wskazać inny obiekt. Tak więc, wszystko co musisz zrobić, aby usunąć obiekt, upewnij się, że nie ma na nim żadnych oznaczeń. Na przykład. jeśli masz tylko jeden obiekt o nazwie shared_ptr<T> o nazwie p wskazujący obiekt, pozwól mu wypaść poza zakres lub zadzwoń pod numer p.reset() (odpowiednik p = NULL dla zwykłego wskaźnika) lub przypisz go, aby wskazywał coś innego.

Jeśli masz dwa obiekty wskazujące na obiekt, konieczne będzie ponowne przypisanie obu.

EDIT: Dzięki dehmann za wskazanie, że p = NULL; rzeczywistości nie jest poprawny kod dla shared_ptr<T> ... :)

+3

Brzmi dobrze, ale jedno: nie można pisać p = NULL, ponieważ p to shared_ptr, a nie wskaźnik. – Frank

+1

Tak, dla pokrewnego pytania dotyczącego używania NULL podczas używania shared_ptrs, zobacz http://stackoverflow.com/questions/621220/null-pointer-with-boostsharedptr/621249#621249 –

+1

@dehmann: Whoops, jesteś absolutnie right ... –

4

Co chcesz zrobić, to wrócić słabych referencji za pomocą boost::weak_ptr, które można przekształcić w shared_ptr w razie potrzeby. To pozwala ci kontrolować czas życia obiektu w shared_ptr, a ci, którzy chcą uzyskać do niego dostęp, mogą trzymać się weak_ptr i spróbować przekonwertować na shared_ptr. Jeśli ta konwersja się nie powiedzie, mogą ponownie zapytać i przywrócić obiekt do pamięci.

9

Jeśli chcesz mieć możliwość celowego usuwania obiektów (robię to przez cały czas), musisz użyć pojedynczego właściciela. Zostałeś przyciągnięty do używania shared_ptr, gdy nie jest odpowiedni do twojego projektu.

Powiązane problemy