C ++ 03
std::auto_ptr
- Być może jeden z oryginałów, który cierpiał na syndrom pierwszego przeciągu, zapewniał tylko ograniczone możliwości wywozu śmieci. Pierwszą wadą jest to, że wywołuje delete
zniszczenie, co czyni je niedopuszczalnymi do przechowywania obiektów przydzielonych do tablicy ( new[]
). Przejmuje na własność wskaźnik, więc dwa automatyczne wskaźniki nie powinny zawierać tego samego obiektu. Przypisanie spowoduje przeniesienie własności i zresetuje automatyczny wskaźnik rvalue do pustego wskaźnika. Co prowadzi do prawdopodobnie najgorszej wady; nie można ich używać w kontenerach STL ze względu na wspomnianą powyżej niemożność kopiowania. Ostatnim ciosem dla każdego przypadku użycia jest to, że zostaną one uznane za przestarzałe w następnym standardzie C ++.
std::auto_ptr_ref
- To nie jest inteligentny wskaźnik, w rzeczywistości jest to szczegół projektowy używany w połączeniu z std::auto_ptr
możliwością kopiowania i przypisywania w określonych sytuacjach. W szczególności można go użyć do konwersji wartości innej niż std::auto_ptr
stała na lwartość przy użyciu sztuczki Colvin-Gibbons, znanej również jako konstruktor przenoszenia, aby przenieść własność.
Wręcz przeciwnie, być może std::auto_ptr
tak naprawdę nie był przeznaczony do stosowania jako inteligentny wskaźnik ogólnego przeznaczenia do automatycznego czyszczenia pamięci. Większość mojego ograniczonego rozumienia i przypuszczeń opiera się na efektywnym użyciu auto_ptr Herba Suttera i używam go regularnie, chociaż nie zawsze w najbardziej zoptymalizowany sposób.
C ++ 11
std::unique_ptr
- To nasz przyjaciel, który będzie zastąpienie std::auto_ptr
będzie bardzo podobny z wyjątkiem najważniejszych ulepszeń w celu skorygowania słabości std::auto_ptr
jak praca z tablicami, lwartości ochrony poprzez prywatnego konstruktora kopiowania, użytkować z kontenerów STL i algorytmów itp Ponieważ jest to wydajność napowietrznych a ślad pamięciowy jest ograniczony, jest to idealny kandydat do zastąpienia, lub być może trafniej opisanego jako posiadanie, surowych wskaźników. Jak sugeruje „unikalny”, istnieje tylko jeden właściciel wskaźnika, tak jak poprzedni std::auto_ptr
.
std::shared_ptr
- Uważam, że jest to oparte na TR1 i boost::shared_ptr
ulepszone, aby uwzględnić również aliasing i arytmetykę wskaźnika. Krótko mówiąc, otacza on liczony w referencjach inteligentny wskaźnik wokół dynamicznie przydzielonego obiektu. Ponieważ „udostępniony” oznacza, że wskaźnik może być własnością więcej niż jednego wskaźnika współdzielonego, gdy ostatnie odwołanie do ostatniego wskaźnika udostępnionego wychodzi poza zakres, wówczas obiekt zostanie odpowiednio usunięty. Są one również bezpieczne dla wątków i w większości przypadków mogą obsługiwać niekompletne typy. std::make_shared
może służyć do wydajnego konstruowania std::shared_ptr
alokacji z jedną stertą przy użyciu domyślnego alokatora.
std::weak_ptr
- Podobnie w oparciu o TR1 i boost::weak_ptr
. Jest to odwołanie do obiektu należącego do a std::shared_ptr
i dlatego nie zapobiegnie usunięciu obiektu, jeśli std::shared_ptr
liczba odwołań spadnie do zera. Aby uzyskać dostęp do surowego wskaźnika, musisz najpierw uzyskać dostęp do std::shared_ptr
przez wywołanie, lock
które zwróci wartość pustą, std::shared_ptr
jeśli posiadany wskaźnik wygasł i został już zniszczony. Jest to przydatne przede wszystkim w celu uniknięcia nieskończonej liczby zawieszonych odwołań podczas korzystania z wielu inteligentnych wskaźników.
Podnieść
boost::shared_ptr
- Prawdopodobnie najłatwiejszy w użyciu w różnych scenariuszach (STL, PIMPL, RAII itp.) Jest to wspólny inteligentny wskaźnik liczony z odniesieniami. Słyszałem kilka skarg dotyczących wydajności i kosztów ogólnych w niektórych sytuacjach, ale musiałem je zignorować, ponieważ nie pamiętam, o co chodzi. Najwyraźniej był na tyle popularny, że stał się oczekującym standardowym obiektem C ++ i nie przychodzą na myśl żadne wady w stosunku do normy dotyczącej inteligentnych wskaźników.
boost::weak_ptr
- Podobnie jak w poprzednim opisie std::weak_ptr
, w oparciu o tę implementację, umożliwia to odniesienie do pliku boost::shared_ptr
. Nic dziwnego, że wywołujesz lock()
dostęp do „silnego” wskaźnika współdzielonego i musisz sprawdzić, czy jest on prawidłowy, ponieważ mógł już zostać zniszczony. Po prostu upewnij się, że nie przechowujesz zwróconego wskaźnika udostępnionego i pozwól mu wyjść poza zakres, gdy tylko skończysz z nim, w przeciwnym razie wrócisz do problemu z cyklicznymi odwołaniami, w którym liczba odwołań się zawiesi, a obiekty nie zostaną zniszczone.
boost::scoped_ptr
- Jest to prosta, inteligentna klasa wskaźnika z niewielkim narzutem, prawdopodobnie zaprojektowana jako lepsza alternatywa, boost::shared_ptr
gdy jest użyteczna. Jest to porównywalne std::auto_ptr
zwłaszcza z tym, że nie można go bezpiecznie używać jako elementu kontenera STL lub z wieloma wskaźnikami do tego samego obiektu.
boost::intrusive_ptr
- Nigdy tego nie używałem, ale z mojego zrozumienia jest to przeznaczone do użycia podczas tworzenia własnych klas kompatybilnych z inteligentnymi wskaźnikami. Musisz sam zaimplementować liczenie odwołań, musisz również zaimplementować kilka metod, jeśli chcesz, aby Twoja klasa była ogólna, a ponadto musisz zaimplementować własne zabezpieczenie wątków. Z drugiej strony prawdopodobnie daje to najbardziej niestandardowy sposób wybierania i wybierania dokładnie tego, ile lub jak mało „sprytu” chcesz. intrusive_ptr
jest zazwyczaj bardziej wydajne niż, shared_ptr
ponieważ umożliwia przydzielenie jednej sterty na obiekt. (dzięki Arvid)
boost::shared_array
- To jest boost::shared_ptr
dla tablic. Zasadniczo new []
, operator[]
i oczywiście delete []
są zapiekane. To może być używane w pojemnikach STL i o ile wiem, robi wszystko boost:shared_ptr
, chociaż nie można boost::weak_ptr
z nimi używać . Możesz jednak alternatywnie użyć boost::shared_ptr<std::vector<>>
do podobnej funkcji i odzyskać możliwość korzystania boost::weak_ptr
z referencji.
boost::scoped_array
- To jest boost::scoped_ptr
dla tablic. Podobnie jak w przypadku boost::shared_array
wszystkich niezbędnych dobrodziejstw tablicy, ta jest nie do kopiowania i dlatego nie może być używana w kontenerach STL. Znalazłem prawie wszędzie, gdzie chcesz tego użyć, prawdopodobnie możesz po prostu użyć std::vector
. Nigdy nie ustaliłem, która jest w rzeczywistości szybsza lub ma mniejszy narzut, ale ta ograniczona tablica wydaje się znacznie mniej zaangażowana niż wektor STL. Jeśli chcesz zachować alokację na stosie, rozważ boost::array
zamiast tego.
Qt
QPointer
- Wprowadzony w Qt 4.0 jest to „słaby” inteligentny wskaźnik, który działa tylko z QObject
klasami pochodnymi, co w ramach Qt jest prawie wszystkim, więc nie jest to tak naprawdę ograniczenie. Istnieją jednak ograniczenia, a mianowicie to, że nie dostarcza on „silnego” wskaźnika i chociaż możesz sprawdzić, czy podstawowy obiekt jest prawidłowy, isNull()
możesz znaleźć obiekt, który został zniszczony zaraz po przejściu tego sprawdzenia, szczególnie w środowiskach wielowątkowych. Qt ludzie uważają to za przestarzałe, jak sądzę.
QSharedDataPointer
- Jest to „silny” inteligentny wskaźnik, który może być porównywalny, boost::intrusive_ptr
chociaż ma pewne wbudowane zabezpieczenia wątków, ale wymaga uwzględnienia metod zliczania odwołań ( ref
i deref
), co można zrobić przez tworzenie podklas QSharedData
. Podobnie jak w przypadku większości Qt, obiekty są najlepiej używane poprzez szerokie dziedziczenie, a tworzenie podklas wydaje się być zgodne z zamierzonym projektem.
QExplicitlySharedDataPointer
- Bardzo podobny do QSharedDataPointer
tego, że nie wywołuje niejawnie detach()
. Nazwałbym tę wersję 2.0, QSharedDataPointer
ponieważ ten niewielki wzrost kontroli co do dokładnego momentu odłączenia po spadku liczby referencji do zera nie jest szczególnie warty zupełnie nowego obiektu.
QSharedPointer
- Atomowe liczenie odniesień, bezpieczeństwo wątków, wskaźnik współdzielenia, niestandardowe usuwanie (obsługa tablic), brzmi tak, jak wszystko, co powinien być inteligentny wskaźnik. To jest to, czego używam przede wszystkim jako inteligentny wskaźnik w Qt i uważam go za porównywalny, boost:shared_ptr
chociaż prawdopodobnie znacznie bardziej narzut, jak wiele obiektów w Qt.
QWeakPointer
- Czy wyczuwasz powtarzający się wzór? Tak jak std::weak_ptr
i boost::weak_ptr
jest to używane w połączeniu z sytuacją, QSharedPointer
gdy potrzebujesz odwołań między dwoma inteligentnymi wskaźnikami, które w przeciwnym razie spowodowałyby, że obiekty nigdy nie zostałyby usunięte.
QScopedPointer
- Ta nazwa powinna również wyglądać znajomo i faktycznie była oparta na boost::scoped_ptr
odmiennych wersjach Qt wspólnych i słabych wskaźników. Działa w celu zapewnienia inteligentnego wskaźnika dla pojedynczego właściciela, bez narzutu, QSharedPointer
który sprawia, że jest bardziej odpowiedni dla zgodności, kodu bezpiecznego dla wyjątków i wszystkich rzeczy, których możesz użyć std::auto_ptr
lub boost::scoped_ptr
do których.