Co to jest inteligentny wskaźnik i kiedy należy go używać?

Co to jest inteligentny wskaźnik i kiedy go używać?

Author: 0x6900, 2008-09-20

14 answers

Inteligentny wskaźnik jest klasą, która owija "surowy" (lub "goły") wskaźnik C++, aby zarządzać czasem życia wskazywanego obiektu. Nie ma jednego inteligentnego typu wskaźnika, ale wszystkie z nich starają się abstrakcji surowego wskaźnika w praktyczny sposób.

Inteligentne wskaźniki powinny być preferowane niż surowe wskaźniki. Jeśli uważasz, że potrzebujesz użyć wskaźników (najpierw zastanów się, czy naprawdę to zrobić), Zwykle chcesz użyć inteligentnego wskaźnika, ponieważ może to złagodzić wiele problemów z surowymi wskaźnikami, głównie zapominając o usunięciu obiektu i wyciekającej pamięci.

Z surowymi wskaźnikami, programista musi jawnie zniszczyć obiekt, gdy nie jest już użyteczny.

// Need to create the object to achieve some goal
MyObject* ptr = new MyObject(); 
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?

Inteligentny wskaźnik dla porównania definiuje politykę dotyczącą czasu zniszczenia obiektu. Nadal musisz stworzyć obiekt, ale nie musisz się już martwić o jego zniszczenie.

SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.

// Destruction of the object happens, depending 
// on the policy the smart pointer class uses.

// Destruction would happen even if DoSomething() 
// raises an exception

Najprostsza zasada w użyciu obejmuje zakres obiektu smart pointer wrapper, np. zaimplementowanego przez boost::scoped_ptr lub std::unique_ptr.

void f()
{
    {
       boost::scoped_ptr<MyObject> ptr(new MyObject());
       ptr->DoSomethingUseful();
    } // boost::scopted_ptr goes out of scope -- 
      // the MyObject is automatically destroyed.

    // ptr->Oops(); // Compile error: "ptr" not defined
                    // since it is no longer in scope.
}

Zauważ, że scoped_ptr instancje nie mogą być kopiowane. Zapobiega to wielokrotnemu (niepoprawnemu) usuwaniu wskaźnika. Możesz jednak przekazać odniesienia do niego do innych funkcji, które wywołujesz.

Wskaźniki zakresowe są przydatne, gdy chcesz powiązać czas życia obiektu z określonym blokiem kodu lub jeśli osadzono go jako dane członkowskie wewnątrz innego obiektu, czas życia tego innego obiektu. Obiekt istnieje aż do blok zawierający kod jest zamykany lub dopóki obiekt zawierający nie zostanie sam zniszczony.

Bardziej złożona Polityka inteligentnego wskaźnika polega na zliczaniu wskaźnika. Pozwala to na skopiowanie wskaźnika. Gdy ostatnie" odniesienie " do obiektu zostanie zniszczone, obiekt zostanie usunięty. Niniejsza polityka jest realizowana przez boost::shared_ptr oraz std::shared_ptr.

void f()
{
    typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
    MyObjectPtr p1; // Empty

    {
        MyObjectPtr p2(new MyObject());
        // There is now one "reference" to the created object
        p1 = p2; // Copy the pointer.
        // There are now two references to the object.
    } // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero. 
  // The object is deleted.

Wskaźniki referencyjne są bardzo przydatne, gdy żywotność obiektu jest znacznie bardziej skomplikowana i jest nie jest związany bezpośrednio z określoną sekcją kodu lub z innym obiektem.

Istnieje jedna wada w odniesieniu liczonych wskaźników - możliwość tworzenia zwisającego odniesienia:

// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!

Inną możliwością jest tworzenie odniesień kołowych:

struct Owner {
   boost::shared_ptr<Owner> other;
};

boost::shared_ptr<Owner> p1 (new Owner());
boost::shared_ptr<Owner> p2 (new Owner());
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1

// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!
Aby obejść ten problem, zarówno Boost, jak i C++11 zdefiniowały weak_ptr, aby zdefiniować słabe (niezliczone) odniesienie do shared_ptr.

UPDATE

[[19]}ta odpowiedź jest dość stara, a więc opisuje to, co było "dobre" w tym czasie, czyli inteligentne wskaźniki dostarczone przez Bibliotekę Boost. Od C++11 biblioteka standardowa ma wystarczającą ilość typów inteligentnych wskaźników, dlatego warto korzystać z std::unique_ptr, std::shared_ptr oraz std::weak_ptr.

Istnieje również std::auto_ptr. Jest bardzo podobny do wskaźnika lunetowego, z tym, że ma również" specjalną " niebezpieczną zdolność do kopiowania-która również nieoczekiwanie przenosi własność! jest przestarzały w najnowszych standardach, więc nie należy go używać. Użyj std::unique_ptr zamiast tego.

std::auto_ptr<MyObject> p1 (new MyObject());
std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership. 
                                 // p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.
 1671
Author: Lloyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-12 22:15:59

Oto prosta odpowiedź na te dni współczesnego C++:

  • Co to jest inteligentny wskaźnik?
    Jest to typ, którego wartości mogą być używane jak wskaźniki, ale który zapewnia dodatkową funkcję automatycznego zarządzania pamięcią: gdy inteligentny wskaźnik nie jest już używany, pamięć, na którą wskazuje, jest dealokowana(patrz także bardziej szczegółowa definicja na Wikipedii ).
  • Kiedy należy go użyć?
    W kodzie, który polega na śledzeniu własności kawałek pamięci, przydzielanie lub dealowanie; inteligentny wskaźnik często oszczędza Ci potrzebę zrobienia tych rzeczy jawnie.
  • ale który inteligentny wskaźnik powinienem użyć w którym z tych przypadków?
    • użycie std::unique_ptr Jeśli nie zamierzasz przechowywać wielu odniesień do tego samego obiektu. Na przykład, użyj go do wskaźnika do pamięci, który jest przydzielany po wejściu do określonego zakresu i dealowany po wyjściu z zakresu.
    • użycie std::shared_ptr kiedy chcesz odnosić się do Twój obiekt z wielu miejsc - i nie chcesz, aby został rozdzielony, dopóki wszystkie te odniesienia nie znikną.
    • użycie std::weak_ptr Jeśli chcesz odwoływać się do obiektu z wielu miejsc - dla tych odwołań, dla których można ignorować i dealokować (więc po prostu zauważą, że obiekt zniknął podczas próby dereferencji).
    • nie używaj inteligentnych wskaźników boost:: lub std::auto_ptr z wyjątkiem specjalnych przypadków, które możesz przeczytać, jeśli muszę.
  • Hej, nie pytałem, którego użyć!
    Ale naprawdę chciałeś to przyznać.
  • więc kiedy powinienem używać zwykłych wskaźników?
    Głównie w kodzie, który jest nieświadomy własności pamięci. Zazwyczaj dotyczy to funkcji, które otrzymują wskaźnik z innego miejsca i nie przydzielają, nie przydzielają ani nie przechowują kopii wskaźnika, który przewyższa ich wykonanie.
 182
Author: einpoklum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-11 10:36:59

Smart pointer to typ podobny do wskaźnika z dodatkowymi funkcjami, np. automatyczną dealokacją pamięci, zliczaniem referencji itp.

Małe intro jest dostępne na stronie Inteligentne Wskaźniki - co, Dlaczego, które?.

Jednym z prostych inteligentnych wskaźników typu jest std::auto_ptr (rozdział 20.4.5 standardu C++), który pozwala automatycznie dealokować pamięć, gdy jest poza zasięgiem i który jest bardziej wytrzymały niż zwykłe użycie wskaźnika, gdy wyjątki są wyrzucane, chociaż mniej elastyczny.

Innym wygodnym typem jest boost::shared_ptr który implementuje zliczanie referencji i automatycznie dealokuje pamięć, gdy nie ma odniesień do obiektu. Pomaga to uniknąć wycieków pamięci i jest łatwe w użyciu do implementacji RAII .

[[2]}Temat został szczegółowo omówiony w książce "C++ Templates: The Complete Guide" autorstwa Davida Vandevoorde, Nicolai M. Josuttis , rozdział Rozdział 20. Inteligentne Wskaźniki. Niektóre tematy:
  • Ochrona Przed Wyjątki
  • W przeciwieństwie do innych inteligentnych wskaźników, nie jest to możliwe.]}
  • W języku C++proces pozyskiwania zasobów jest często używany do bezpiecznego zarządzania zasobami (exception-safe resource management).]}
  • Ograniczenia Posiadacza
  • Zliczanie Referencji
  • Współbieżny Dostęp Licznika
  • zniszczenie i Dealokacja
 99
Author: sergtk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-17 18:12:03

Definicje Dostarczone przez Chrisa, Sergdeva i Llyoda są poprawne. Wolę jednak prostszą definicję, żeby moje życie było proste: Inteligentny wskaźnik jest po prostu klasą przeciążającą operatory -> i *. Co oznacza, że Twój obiekt semantycznie wygląda jak wskaźnik, ale możesz zrobić z niego fajniejsze rzeczy, w tym zliczanie referencji, automatyczne niszczenie itp. shared_ptr i auto_ptr są wystarczające w większości przypadków, ale wraz z własnym zestawem małych idiosynkrazji.

 34
Author: Sridhar Iyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-07 14:45:31

Inteligentny wskaźnik jest jak zwykły (wpisany) wskaźnik, jak " char*", z wyjątkiem, gdy wskaźnik sam wychodzi poza zakres, to to, co wskazuje, jest również usuwane. Możesz użyć go tak, jak zwykłego wskaźnika, używając " ->", ale nie, jeśli potrzebujesz rzeczywistego wskaźnika do danych. W tym celu możesz użyć "& * ptr".

Jest to przydatne dla:

  • Obiekty, które muszą być przydzielone jako nowe, ale które chcesz mieć taki sam okres życia jak coś na tym stosie. Jeśli obiekt jest przypisane do inteligentnego wskaźnika, a następnie zostaną usunięte, gdy program zakończy tę funkcję/blok.

  • Dane klas, tak, że po usunięciu obiektu wszystkie posiadane dane są również usuwane, bez specjalnego kodu w destruktorze (musisz mieć pewność, że Destruktor jest wirtualny, co prawie zawsze jest dobrą rzeczą do zrobienia).

Możesz Nie chcieć użyć inteligentnego wskaźnika, gdy:

  • ... wskaźnik nie powinien posiadać data... to znaczy, kiedy po prostu używasz danych, ale chcesz, aby przetrwały funkcję, w której się do niej odwołujesz.
  • ... inteligentny wskaźnik nie zostanie w pewnym momencie zniszczony. Nie chcesz, aby znajdował się w pamięci, która nigdy nie zostanie zniszczona (na przykład w obiekcie, który jest dynamicznie alokowany, ale nie zostanie wyraźnie usunięty).
  • ... dwa inteligentne wskaźniki mogą wskazywać na te same dane. (Istnieją jednak jeszcze mądrzejsze wskaźniki, które sobie z tym poradzą... to się nazywa liczenie referencji .)

Zobacz też:

 27
Author: markets,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:48

Większość rodzajów inteligentnych wskaźników obsługuje usuwanie wskaźnika-aby obiekt za Ciebie. Jest to bardzo przydatne, ponieważ nie musisz już myśleć o ręcznym usuwaniu obiektów.

Najczęściej używanymi inteligentnymi wskaźnikami są std::tr1::shared_ptr (LUB boost::shared_ptr), a rzadziej std::auto_ptr. Polecam regularne stosowanie shared_ptr.

shared_ptr jest bardzo wszechstronny i zajmuje się wieloma różnymi scenariuszami usuwania, w tym przypadkami, w których obiekty muszą być "przekazywane przez granice DLL" (wspólny koszmar przypadek, jeśli pomiędzy Twoim kodem a bibliotekami DLL są używane różne libcs).

 15
Author: Chris Jester-Young,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-20 00:14:52

Inteligentny wskaźnik to obiekt, który działa jak wskaźnik, ale dodatkowo zapewnia kontrolę nad budową, niszczeniem, kopiowaniem, przenoszeniem i dereferencją.

Można zaimplementować własny inteligentny wskaźnik, ale wiele bibliotek zapewnia również implementacje inteligentnych wskaźników, każda z różnymi zaletami i wadami.

Na przykład, Boost zapewnia następujące implementacje inteligentnego wskaźnika:

  • shared_ptr<T> jest wskaźnikiem do T wykorzystującym liczbę referencji aby określić, kiedy obiekt nie jest już potrzebny.
  • {[2] } jest wskaźnik automatycznie usuwany, gdy wychodzi poza zakres. Żaden przydział nie jest możliwy.
  • intrusive_ptr<T> jest kolejnym wskaźnikiem zliczającym odniesienia. Zapewnia lepszą wydajność niż shared_ptr, ale wymaga typu T, aby zapewnić własny mechanizm liczenia odniesienia.
  • {[6] } jest słabym wskaźnikiem, działającym w połączeniu z shared_ptr, Aby uniknąć odniesień okrągłych.
  • shared_array<T> jest jak shared_ptr, ale dla tablic z T.
  • scoped_array<T> jest jak scoped_ptr, ale dla tablic T.

Są to tylko jeden liniowy Opis każdego z nich i mogą być używane zgodnie z potrzebami, po dalsze szczegóły i przykłady można zajrzeć do dokumentacji Boost.

Dodatkowo, biblioteka standardowa C++ zapewnia trzy inteligentne wskaźniki: std::unique_ptr dla unikalnej własności, {[15] } dla współdzielonej własności i std::weak_ptr. std::auto_ptr istniał w C++03, ale obecnie jest przestarzały.

 15
Author: Saqlain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-12 10:03:48

Oto Link do podobnych odpowiedzi : http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

Inteligentny wskaźnik to obiekt, który działa, wygląda i czuje się jak normalny wskaźnik, ale oferuje więcej funkcjonalności. W C++ inteligentne wskaźniki są zaimplementowane jako klasy szablonów, które zawierają wskaźnik i zastępują standardowe operatory wskaźników. Mają one wiele zalet w stosunku do zwykłych wskaźników. Gwarantują, że zostaną zainicjowane jako albo wskaźniki null lub wskaźniki do obiektu heap. Sprawdzana jest Indirection za pomocą wskaźnika null. Nie jest konieczne usuwanie. Obiekty są automatycznie zwalniane, gdy zniknie ostatni wskaźnik do nich. Jednym z istotnych problemów z tymi inteligentnymi wskaźnikami jest to, że w przeciwieństwie do zwykłych wskaźników, nie szanują dziedziczenia. Inteligentne wskaźniki są nieatrakcyjne dla kodu polimorficznego. Poniżej podano przykład implementacji inteligentnych wskaźników.

Przykład:

template <class X>
class smart_pointer
{
          public:
               smart_pointer();                          // makes a null pointer
               smart_pointer(const X& x)            // makes pointer to copy of x

               X& operator *( );
               const X& operator*( ) const;
               X* operator->() const;

               smart_pointer(const smart_pointer <X> &);
               const smart_pointer <X> & operator =(const smart_pointer<X>&);
               ~smart_pointer();
          private:
               //...
};

Ta klasa zaimplementuj inteligentny wskaźnik do obiektu typu X. sam obiekt znajduje się na stercie. Oto jak go używać:

smart_pointer <employee> p= employee("Harris",1333);

Podobnie jak inne przeciążone operatory, p będzie zachowywał się jak zwykły wskaźnik,

cout<<*p;
p->raise_salary(0.5);
 10
Author: Santosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-07 09:03:03

Http://en.wikipedia.org/wiki/Smart_pointer

W informatyce inteligentny wskaźnik jest abstrakcyjnym typem danych, który symuluje wskaźnik, zapewniając dodatkowe funkcje, takie jak automatyczne zbieranie śmieci lub sprawdzanie granic. Te dodatkowe funkcje są przeznaczone aby zmniejszyć błędy spowodowane niewłaściwym wykorzystaniem wskaźniki przy zachowaniu efektywności. Inteligentne Wskaźniki zazwyczaj śledzą obiekty, które wskazują na nie dla cel pamięci zarządzanie. Na nadużywanie wskaźników jest głównym źródłem of bugs: the constant allocation, dealokacja i odwoływanie się do tego, co musi być wykonywane przez program napisany używanie wskaźników sprawia, że jest to bardzo prawdopodobne że pojawią się wycieki pamięci. Inteligentne Wskaźniki starają się zapobiegać pamięci przecieki poprzez zrobienie zasobu dealokacja automatyczna: gdy wskaźnik do obiektu (lub ostatni w seria wskaźników) jest niszczona, dla przykład, ponieważ wychodzi poza zakres, wskazanym obiektem jest zniszczony też.

 8
Author: Jorge Ferreira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-20 00:12:10

Niech T będzie klasą w tym tutorialu Wskaźniki W C++ można podzielić na 3 typy:

1) raw pointers :

T a;  
T * _ptr = &a; 

Przechowują adres pamięci do miejsca w pamięci. Używaj ostrożnie, ponieważ programy stają się skomplikowane, trudne do śledzenia.

Wskaźniki z danymi const lub adresem { odczyt wstecz }

T a ; 
const T * ptr1 = &a ; 
T const * ptr1 = &a ;

Wskaźnik do typu danych t, który jest const. Oznacza to, że nie można zmienić typu danych za pomocą wskaźnika. ie *ptr1 = 19; nie zadziała. Ale ty może przesunąć wskaźnik. ie ptr1++ , ptr1--; etc będzie działać. Czytaj wstecz: wskaźnik do typu T, który jest const

  T * const ptr2 ;

Wskaźnik const do typu danych T . Oznacza to, że nie można przesunąć wskaźnika, ale można zmienić wartość wskazywaną przez wskaźnik. ie *ptr2 = 19 będzie działać, ale ptr2++ ; ptr2-- itd NIE BĘDZIE DZIAŁAĆ. Odczyt wstecz: wskaźnik const do typu T

const T * const ptr3 ; 

Wskaźnik const do typu danych const T . Oznacza to, że nie można ani przesunąć wskaźnika, ani zmienić wskaźnika typu danych na pointer. ie . ptr3-- ; ptr3++ ; *ptr3 = 19; nie zadziała

3) Inteligentne Wskaźniki : { #include <memory> }

Shared Pointer :

  T a ; 
     //shared_ptr<T> shptr(new T) ; not recommended but works 
     shared_ptr<T> shptr = make_shared<T>(); // faster + exception safe

     std::cout << shptr.use_count() ; // 1 //  gives the number of " 
things " pointing to it. 
     T * temp = shptr.get(); // gives a pointer to object

     // shared_pointer used like a regular pointer to call member functions
      shptr->memFn();
     (*shptr).memFn(); 

    //
     shptr.reset() ; // frees the object pointed to be the ptr 
     shptr = nullptr ; // frees the object 
     shptr = make_shared<T>() ; // frees the original object and points to new object

Zaimplementowane za pomocą zliczania referencji, aby śledzić, ile "rzeczy" wskazuje na obiekt wskazywany przez wskaźnik. Gdy liczba ta dojdzie do 0, obiekt jest automatycznie usuwany, tzn. sprzeciw jest usuwany, gdy wszystkie share_ptr wskazujące na obiekt wychodzi poza zakres. Dzięki temu pozbędziesz się bólu głowy związanego z usuwaniem obiektów, które zostały przydzielone przy użyciu nowego.

Słaby Wskaźnik: Pomaga radzić sobie z cyklicznym odniesieniem, które powstaje podczas używania współdzielonego wskaźnika Jeśli masz dwa obiekty wskazywane przez dwa współdzielone wskaźniki i istnieje wewnętrzny współdzielony wskaźnik wskazujący na siebie nawzajem współdzielony wskaźnik, to będzie cykliczne odniesienie i Obiekt nie zostanie usunięty, gdy współdzielone wskaźniki wyjdą poza zakres. Aby to rozwiązać, Zmień Wewnętrzny element z shared_ptr na weak_ptr. Uwaga: aby uzyskać dostęp do elementu wskazywany przez słaby wskaźnik za pomocą lock() , zwraca weak_ptr.

T a ; 
shared_ptr<T> shr = make_shared<T>() ; 
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr 
wk.lock()->memFn() ; // use lock to get a shared_ptr 
//   ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access

Zobacz: kiedy std:: weak_ptr jest przydatne?

Unikalny Wskaźnik: Lekki inteligentny wskaźnik z wyłączną własnością. Użyj, gdy wskaźnik wskazuje na unikalne obiekty bez współdzielenia obiektów między wskaźnikami.

unique_ptr<T> uptr(new T);
uptr->memFn(); 

//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr 

Aby zmienić obiekt wskazywany przez unikalny ptr, użyj semantyki move

unique_ptr<T> uptr1(new T);
unique_ptr<T> uptr2(new T);
uptr2 = std::move(uptr1); 
// object pointed by uptr2 is deleted and 
// object pointed by uptr1 is pointed to by uptr2
// uptr1 becomes null 

: Mogą być zasadniczo jak wskaźnik const, czyli wskaźnik, który jest const i nie może być przeniesiony z lepszą składnią.

Zobacz: jakie są różnice między zmienną wskaźnika a zmienną odniesienia w C++?

r-value reference : reference to a temporary object   
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified 

Odniesienie : https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ Dzięki Andre za zwrócenie uwagi na to pytanie.

 4
Author: nnrales,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:28

Inteligentny wskaźnik jest klasą, opakowaniem zwykłego wskaźnika. W przeciwieństwie do zwykłych wskaźników, koło życia smart point opiera się na liczbie referencji (ile razy obiekt inteligentnego wskaźnika jest przypisany). Więc za każdym razem, gdy inteligentny wskaźnik jest przypisany do innego, wewnętrzna liczba referencji PLUS plus. I kiedy obiekt wychodzi poza zasięg, licznik odniesienia minus minus.

Wskaźnik Automatyczny, choć wygląda podobnie, jest zupełnie inny niż wskaźnik inteligentny. Jest to wygodna klasa, która dealokuje zasób, gdy automatyczny obiekt wskaźnika wychodzi poza zakres zmiennych. W pewnym stopniu sprawia, że wskaźnik (do dynamicznie przydzielanej pamięci) działa podobnie do zmiennej stosu (statycznie przydzielanej w czasie kompilacji).

 3
Author: Trombe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-07 07:54:02

Inteligentne Wskaźniki to te, w których nie musisz się martwić o Dealokację pamięci, dzielenie się zasobami i Transfer.

Można bardzo dobrze używać tych wskaźników w podobny sposób, jak każda alokacja działa w Javie. W Javie Garbage Collector robi sztuczkę, podczas gdy w inteligentnych wskaźnikach sztuczka jest wykonywana przez destruktory.

 2
Author: Daksh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-07 04:07:54

Istniejące odpowiedzi są dobre, ale nie obejmują, co zrobić, gdy inteligentny wskaźnik nie jest (kompletną) odpowiedzią na problem, który próbujesz rozwiązać.

Między innymi (dobrze wyjaśnione w innych odpowiedziach) użycie inteligentnego wskaźnika jest możliwym rozwiązaniem Jak używać klasy abstrakcyjnej jako typu zwracania funkcji? który został oznaczony jako DUPLIKAT tego pytania. Jednak pierwsze pytanie, które należy zadać, czy można określić abstrakcyjną (a właściwie dowolną) klasę bazową jako zwrot wpisz w C++ to " co naprawdę masz na myśli?". Istnieje dobre omówienie (z dalszymi odniesieniami) idiomatycznego programowania obiektowego w C++ (i jak różni się to od innych języków) w dokumentacji boost pointer container library. Podsumowując, w C++ trzeba myśleć o własności. Które Inteligentne Wskaźniki Pomagają, ale nie są jedynym rozwiązaniem lub zawsze kompletnym rozwiązaniem (nie dają kopii polimorficznej) i nie zawsze są rozwiązaniem, które chcesz expose w interfejsie (a powrót funkcji brzmi strasznie jak interfejs). Może to być wystarczające, aby zwrócić odniesienie, na przykład. Jednak we wszystkich tych przypadkach (inteligentny wskaźnik, kontener wskaźnika lub po prostu zwracanie referencji) zmieniono zwrot z wartości na jakąś formę referencji . Jeśli naprawdę potrzebujesz kopii, możesz dodać więcej "idiomu" lub wyjść poza idiomatyczny (lub inny) OOP w C++ do bardziej generycznego polimorfizmu przy użyciu bibliotek jak Adobe Poly lub Boost.TypeErasure .

 1
Author: da77a,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-26 03:10:57

Chciałbym dodać jeszcze jeden punkt do powyższego pytania, smart pointer std:: shared_ptr nie ma operatora dolnego i nie obsługuje arytmetyki pontera, możemy użyć get (), aby uzyskać wbudowany wskaźnik.

 1
Author: suresh m,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-07 13:57:49