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 deletezniszczenie, 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_ptrmoż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_ptrstał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_ptrtak 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_ptrbędzie bardzo podobny z wyjątkiem najważniejszych ulepszeń w celu skorygowania słabości std::auto_ptrjak 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_ptrulepszone, 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_sharedmoże służyć do wydajnego konstruowania std::shared_ptralokacji 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_ptri dlatego nie zapobiegnie usunięciu obiektu, jeśli std::shared_ptrliczba odwołań spadnie do zera. Aby uzyskać dostęp do surowego wskaźnika, musisz najpierw uzyskać dostęp do std::shared_ptrprzez wywołanie, lockktóre zwróci wartość pustą, std::shared_ptrjeś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_ptrgdy jest użyteczna. Jest to porównywalne std::auto_ptrzwł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_ptrjest zazwyczaj bardziej wydajne niż, shared_ptrponieważ umożliwia przydzielenie jednej sterty na obiekt. (dzięki Arvid)
boost::shared_array- To jest boost::shared_ptrdla 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_ptrz nimi używać . Możesz jednak alternatywnie użyć boost::shared_ptr<std::vector<>>do podobnej funkcji i odzyskać możliwość korzystania boost::weak_ptrz referencji.
boost::scoped_array- To jest boost::scoped_ptrdla tablic. Podobnie jak w przypadku boost::shared_arraywszystkich 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::arrayzamiast tego.
Qt
QPointer- Wprowadzony w Qt 4.0 jest to „słaby” inteligentny wskaźnik, który działa tylko z QObjectklasami 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_ptrchociaż ma pewne wbudowane zabezpieczenia wątków, ale wymaga uwzględnienia metod zliczania odwołań ( refi 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 QSharedDataPointertego, że nie wywołuje niejawnie detach(). Nazwałbym tę wersję 2.0, QSharedDataPointerponieważ 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_ptrchociaż prawdopodobnie znacznie bardziej narzut, jak wiele obiektów w Qt.
QWeakPointer- Czy wyczuwasz powtarzający się wzór? Tak jak std::weak_ptri boost::weak_ptrjest to używane w połączeniu z sytuacją, QSharedPointergdy 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_ptrodmiennych 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, QSharedPointerktó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_ptrlub boost::scoped_ptrdo których.