2010-10-07 13 views
6

Mam aplikację C++, która szeroko wykorzystuje wskaźniki do utrzymywania dość skomplikowanych struktur danych. Aplikacja wykonuje symulacje matematyczne na dużych zbiorach danych (co może zająć kilka GB pamięci) i jest kompilowana przy użyciu programu Visual Studio 2010. Microsoft Visual Studio 2010.Pierwsze kroki z inteligentnymi wskaźnikami w C++

Obecnie przerabiałem ważną część aplikacji. Aby zmniejszyć błędy (zwisające wskaźniki, wycieki pamięci, ...) Chciałbym zacząć używać inteligentnych wskaźników. Poświęcanie pamięci lub wydajności jest dopuszczalne, o ile jest ograniczone.

W praktyce większość zajęć jest prowadzona w dużych pulach (jedna pula na klasę) i chociaż klasy mogą się nawzajem odnosić, można uznać pulę za właściciela wszystkich instancji tej klasy. Jeśli jednak pula zdecyduje się usunąć instancję, nie chcę, aby jakakolwiek inna klasa, która wciąż odnosi się do usuniętej instancji, miała zwisający wskaźnik.

W innej części przechowuję zbiór wskaźników dla instancji dostarczanych przez inne moduły w aplikacji. W praktyce pozostałe moduły zachowują własność przekazanej instancji, ale w niektórych przypadkach moduły nie chcą dbać o własność i po prostu chcą przekazać instancję do kolekcji, mówiąc "teraz jest twoje, zarządzaj nią".

Jaki jest najlepszy sposób na rozpoczęcie wprowadzania inteligentnych wskaźników? Zastępowanie wskaźników [losowo] za pomocą inteligentnych wskaźników nie wydaje się poprawne i prawdopodobnie nie zapewnia wszystkich (ani żadnych) zalet inteligentnych wskaźników. Ale jaka jest lepsza metoda?

Jakie typy inteligentnych wskaźników powinienem zbadać dalej? Czasami używam std :: auto_ptr do dealokacji lokalnie przydzielonej pamięci, ale wydaje się, że jest ona usunięta w C++ 0x. Czy std :: unique_ptr jest lepszą alternatywą? A może powinienem udać się bezpośrednio do wspólnych wskaźników lub innych typów inteligentnych wskaźników?

Wydaje się podobne pytanie, ale zamiast pytać, jakie to proste, pytam, jakie jest najlepsze podejście i jaki rodzaj inteligentnych wskaźników najlepiej pasuje.

Z góry dziękuję za pomysły i sugestie.

Odpowiedz

1

Oto znalezione w nowym standardzie C++ 11 3 odmiany (unique_ptr zastępuje auto_ptr)

http://www.stroustrup.com/C++11FAQ.html#std-unique_ptr

http://www.stroustrup.com/C++11FAQ.html#std-shared_ptr

http://www.stroustrup.com/C++11FAQ.html#std-weak_ptr

można przeczytać tekst dla każdego wskaźnika i tam jest wyjaśnienie, kiedy użyć, co tam. W przypadku zarządzania pamięcią lokalną unikalny_ptr jest wyborem. Nie można jej kopiować, ale można ją przesuwać, więc gdy ją przenosisz, odbiornik przejmuje jej własność.

Wspólna_ptr jest używana, jeśli chcesz udostępnić instancję obiektu w pobliżu, gdy nikt naprawdę nie jest właścicielem obiektu i upewnić się, że nie zostanie usunięty, gdy ktoś nadal ma do niego odniesienie. Gdy ostatni użytkownik obiektu niszczy kontener shared_ptr, zawarty obiekt zostanie usunięty.

weak_ptr jest używany w połączeniu z shared_ptr. Umożliwia "zablokowanie", aby sprawdzić, czy referencyjny obiekt shared_ptr nadal istnieje przed próbą uzyskania dostępu do wewnętrznego obiektu.

3

Zalecam używanie, jeśli to możliwe, unique_ptr (może to wymagać analizy programu) i shared_ptr, gdy jest to niemożliwe. W razie wątpliwości należy użyć numeru shared_ptr, aby zmaksymalizować bezpieczeństwo: przy przekazywaniu kontroli do kontenera licznik odwołań po prostu przejdzie do dwóch, a następnie z powrotem do jednego, a kontener docelowo zostanie automatycznie przypisany do powiązanego obiektu delete. Gdy wydajność staje się problemem, rozważ użycie opcji boost::intrusive_ptr.

+0

+1 dobra rada. Musisz wykonać * lot * tworzenia/niszczenia obiektów lub kopiowania wskaźników, aby zobaczyć różnicę w wydajności między 'shared_ptr' i' intrusive_ptr'. – Doug