Wat is een slimme aanwijzer en wanneer moet ik er een gebruiken?

Wat is een slimme aanwijzer en wanneer moet ik er een gebruiken?


Antwoord 1, autoriteit 100%

UPDATE

Dit antwoord is nogal oud en beschrijft dus wat destijds ‘goed’ was, namelijk slimme tips van de Boost-bibliotheek. Sinds C++11 biedt de standaardbibliotheek voldoende slimme aanwijzertypes, en daarom zou u de voorkeur moeten geven aan het gebruik van std::unique_ptr, std::shared_ptren std::weak_ptr.

Er was ook std::auto_ptr. Het leek heel erg op een scoped pointer, behalve dat het ook de “speciale” gevaarlijke mogelijkheid had om te worden gekopieerd – wat ook onverwacht het eigendom overdraagt.
Het was verouderd in C++11 en verwijderd in C++17, dus je zou het niet moeten gebruiken.

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.

OUD ANTWOORD

Een slimme aanwijzer is een klasse die een ‘onbewerkte’ (of ‘kale’) C++-aanwijzer omhult om de levensduur van het object waarnaar wordt verwezen te beheren. Er is niet één type slimme aanwijzer, maar ze proberen allemaal een onbewerkte aanwijzer op een praktische manier te abstraheren.

Slimme aanwijzers hebben de voorkeur boven onbewerkte aanwijzers. Als u denkt dat u aanwijzers moet gebruiken (eerst overwegen of u dit echtdoet), zou u normaal gesproken een slimme aanwijzer willen gebruiken, omdat dit veel van de problemen met onbewerkte aanwijzers kan verlichten, vooral als u vergeet de object en lekkend geheugen.

Bij onbewerkte pointers moet de programmeur het object expliciet vernietigen wanneer het niet langer bruikbaar is.

// 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...?

Een slimme aanwijzer ter vergelijking definieert een beleid met betrekking tot wanneer het object wordt vernietigd. U moet het object nog steeds maken, maar u hoeft zich geen zorgen meer te maken over het vernietigen ervan.

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

Het eenvoudigste beleid dat wordt gebruikt, heeft betrekking op het bereik van het smart pointer wrapper-object, zoals geïmplementeerd door boost::scoped_ptrof std::unique_ptr.

void f()
{
    {
       std::unique_ptr<MyObject> ptr(new MyObject());
       ptr->DoSomethingUseful();
    } // ptr goes out of scope -- 
      // the MyObject is automatically destroyed.
    // ptr->Oops(); // Compile error: "ptr" not defined
                    // since it is no longer in scope.
}

Merk op dat std::unique_ptrinstanties niet kunnen worden gekopieerd. Hiermee wordt voorkomen dat de aanwijzer meerdere keren (onjuist) wordt verwijderd. U kunt er echter wel verwijzingen naar doorgeven aan andere functies die u aanroept.

std::unique_ptrs zijn handig wanneer u de levensduur van het object aan een bepaald codeblok wilt koppelen, of als u het als lidgegevens in een ander object insluit, de levensduur van dat ander voorwerp. Het object bestaat totdat het bevattende codeblok wordt verlaten, of totdat het bevattende object zelf wordt vernietigd.

Een complexer beleid voor slimme aanwijzers omvat het tellen van de aanwijzer. Hierdoor kan de aanwijzer worden gekopieerd. Wanneer de laatste “verwijzing” naar het object wordt vernietigd, wordt het object verwijderd. Dit beleid wordt geïmplementeerd door boost::shared_ptren 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.

Referentie getelde pointers zijn erg handig wanneer de levensduur van uw object veel gecompliceerder is, en niet direct gekoppeld is aan een bepaald stuk code of aan een ander object.

Er is één nadeel aan referentie getelde pointers — de mogelijkheid om een bungelende referentie te creëren:

// 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!

Een andere mogelijkheid is het maken van kringverwijzingen:

struct Owner {
   std::shared_ptr<Owner> other;
};
std::shared_ptr<Owner> p1 (new Owner());
std::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!

Om dit probleem te omzeilen, hebben zowel Boost als C++11 een weak_ptrgedefinieerd om een zwakke (ontelbare) verwijzing naar een shared_ptrte definiëren.


Antwoord 2, autoriteit 18%

Hier is een eenvoudig antwoord voor deze dagen van moderne C++ (C++11 en later):

  • “Wat is een slimme aanwijzer?”
    Het is een type waarvan de waarden kunnen worden gebruikt als aanwijzers, maar die de extra functie van automatisch geheugenbeheer biedt: wanneer een slimme aanwijzer niet langer in gebruik is, wordt het geheugen waarnaar deze verwijst, ongedaan gemaakt (zie ook de meer gedetailleerde definitie op Wikipedia).
  • “Wanneer moet ik er een gebruiken?”
    In code waarbij het eigendom van een stuk geheugen wordt gevolgd, toegewezen of gedealloceerd; de slimme aanwijzer bespaart u vaak de noodzaak om deze dingen expliciet te doen.
  • “Maar welke slimme aanwijzer moet ik in welke van die gevallen gebruiken?”
    • Gebruik std::unique_ptrwanneer u wilt dat uw object net zo lang leeft als een enkele eigendomsreferentie ernaar leeft. Gebruik het bijvoorbeeld voor een verwijzing naar geheugen die wordt toegewezen bij het betreden van een bereik en de-toewijzing bij het verlaten van het bereik.
    • Gebruik std::shared_ptrwanneer u u op meerdere plaatsen naar uw object wilt verwijzen – en niet wilt dat de toewijzing van uw object wordt ongedaan gemaakt totdat al deze verwijzingen zelf zijn verdwenen.
    • Gebruik std::weak_ptrwanneer u wil wel op meerdere plaatsen naar uw object verwijzen – voor die verwijzingen waarvoor het ok is om te negeren en de toewijzing ongedaan te maken (zodat ze zullen merken dat het object weg is wanneer u de verwijzing probeert te verwijderen).
    • Gebruik de boost::slimme aanwijzers of std::auto_ptrniet, behalve in speciale gevallen die u zo nodig kunt lezen.
  • “Hé, ik heb niet gevraagd welke ik moet gebruiken!”
    Ah, maar je wilde het echt toegeven.
  • “Dus wanneer moet ik dan gewone aanwijzers gebruiken?”
    Meestal in code die zich niet bewust is van geheugeneigendom. Dit zou typisch zijn in functies die een aanwijzer van ergens anders krijgen en die niet toewijzen of de-toewijzing ongedaan maken, en die geen kopie van de aanwijzer opslaan die langer meegaat dan de uitvoering ervan.

Antwoord 3, autoriteit 6%

Een slimme aanwijzeris een aanwijzer-achtig type met wat extra functionaliteit, b.v. automatische geheugendeallocatie, referentietelling enz.

Een kleine introductie is beschikbaar op de pagina Slimme aanwijzers – wat, waarom, welke? .

Een van de eenvoudige typen slimme aanwijzers is std::auto_ptr(hoofdstuk 20.4.5 van de C++-standaard), waarmee men automatisch geheugen kan vrijgeven wanneer het buiten het bereik valt en wat robuuster is dan het simpele gebruik van aanwijzers wanneer er uitzonderingen worden gegenereerd, hoewel minder flexibel.

Een ander handig type is boost::shared_ptrdie referentietelling implementeert en automatisch geheugen vrijgeeft wanneer er geen verwijzingen naar het object meer zijn. Dit helpt geheugenlekken te voorkomen en is gemakkelijk te gebruiken om RAIIte implementeren.

Het onderwerp wordt uitgebreid behandeld in het boek “C++ Templates: The Complete Guide” van David Vandevoorde, Nicolai M. Josuttis, hoofdstuk Hoofdstuk 20. Slimme aanwijzers.
Enkele behandelde onderwerpen:

  • Beschermen tegen uitzonderingen
  • Houders, (let op, std::auto_ptris de implementatie van een dergelijke type slimme aanwijzer)
  • Resource Acquisition Is Initialization(Dit wordt vaak gebruikt voor exception-safe resource management in C++ )
  • Beperkingen van de houder
  • Referentietelling
  • Gelijktijdige toegang tot balie
  • Vernietiging en overdracht

Antwoord 4, autoriteit 2%

Definities van Chris, Sergdev en Llyod zijn correct. Ik geef echter de voorkeur aan een eenvoudigere definitie, gewoon om mijn leven simpel te houden:
Een slimme aanwijzer is gewoon een klasse die de operators ->en *overbelast. Wat betekent dat je object er semantisch uitziet als een aanwijzer, maar je kunt het veel coolere dingen laten doen, zoals het tellen van referenties, automatische vernietiging enz.
shared_ptren auto_ptrzijn in de meeste gevallen voldoende, maar hebben hun eigen setje kleine eigenaardigheden.


Antwoord 5, autoriteit 2%

Een slimme aanwijzer is als een gewone (getypte) aanwijzer, zoals “char*”, behalve wanneer de aanwijzer zelf buiten het bereik valt, dan wordt ook datgene verwijderd waarnaar hij verwijst. Je kunt het gebruiken zoals je een gewone aanwijzer zou doen, door “->” te gebruiken, maar niet als je een echte aanwijzer naar de gegevens nodig hebt. Daarvoor kunt u “&*ptr” gebruiken.

Het is handig voor:

  • Objecten die met nieuw moeten worden toegewezen, maar waarvan je dezelfde levensduur wilt hebben als iets op die stapel. Als het object is toegewezen aan een slimme aanwijzer, worden deze verwijderd wanneer het programma die functie/blok verlaat.

  • Gegevensleden van klassen, zodat wanneer het object wordt verwijderd, ook alle eigendomsgegevens worden verwijderd, zonder speciale code in de destructor (u moet er zeker van zijn dat de destructor virtueel is, wat bijna altijd het geval is een goede zaak om te doen).

Misschien wilt u geeneen slimme aanwijzer gebruiken wanneer:

  • … de aanwijzer zou eigenlijk geen eigenaar moeten zijn van de gegevens… d.w.z. wanneer u alleen de gegevens gebruikt, maar u wilt dat deze de functie overleeft waarin u ernaar verwijst.
  • … de slimme aanwijzer zelf zal op een gegeven moment niet vernietigd worden. Je wilt niet dat het in het geheugen blijft staan dat nooit wordt vernietigd (zoals in een object dat dynamisch wordt toegewezen maar niet expliciet wordt verwijderd).
  • … twee slimme aanwijzers kunnen naar dezelfde gegevens verwijzen. (Er zijn echter nog slimmere tips die daarmee kunnen omgaan… dat heet referentietelling.)

Zie ook:


Antwoord 6

Een slimme aanwijzer is een object dat werkt als een aanwijzer, maar daarnaast controle biedt over constructie, vernietiging, kopiëren, verplaatsen en dereferentie.

Je kunt je eigen slimme aanwijzer implementeren, maar veel bibliotheken bieden ook slimme aanwijzer-implementaties, elk met verschillende voor- en nadelen.

Bijvoorbeeld Boostbiedt de volgende slimme aanwijzerimplementaties:

  • shared_ptr<T>is een verwijzing naar Tdie een referentietelling gebruikt om te bepalen wanneer het object niet langer nodig is.
  • scoped_ptr<T>is een pointer die automatisch wordt verwijderd wanneer deze buiten het bereik valt. Er is geen opdracht mogelijk.
  • intrusive_ptr<T>is een andere aanwijzer voor het tellen van referenties. Het levert betere prestaties dan shared_ptr, maar vereist het type Tom zijn eigen referentietelmechanisme te bieden.
  • weak_ptr<T>is een zwakke aanwijzer, die samenwerkt met shared_ptrom kringverwijzingen te vermijden.
  • shared_array<T>is als shared_ptr, maar voor arrays van T.
  • scoped_array<T>is als scoped_ptr, maar voor arrays van T.

Dit is slechts één lineaire beschrijving van elk en kan naar behoefte worden gebruikt, voor meer details en voorbeelden kan men de documentatie van Boost bekijken.

Bovendien biedt de C++-standaardbibliotheek drie slimme aanwijzers; std::unique_ptrvoor uniek eigendom, std::shared_ptrvoor gedeeld eigendom en std::weak_ptr. std::auto_ptrbestond in C++03 maar is nu verouderd.


Antwoord 7

De meeste soorten slimme aanwijzers zorgen voor het weggooien van het aanwijzer-naar-object. Het is erg handig omdat je niet meer hoeft na te denken over het handmatig weggooien van voorwerpen.

De meest gebruikte slimme aanwijzers zijn std::tr1::shared_ptr(of boost::shared_ptr), en, minder vaak, std::auto_ptr. Ik raad aan om shared_ptrregelmatig te gebruiken.

shared_ptris zeer veelzijdig en behandelt een grote verscheidenheid aan verwijderingsscenario’s, inclusief gevallen waarin objecten “over DLL-grenzen moeten worden doorgegeven” (het veelvoorkomende nachtmerriegeval als verschillende libcs worden gebruikt tussen uw code en de DLL’s).


Antwoord 8

Hier is de link voor soortgelijke antwoorden: http://sickprogrammersarea.blogspot. .in/2014/03/technical-interview-questions-on-c_6.html

Een slimme aanwijzer is een object dat werkt, eruitziet en aanvoelt als een normale aanwijzer, maar meer functionaliteit biedt. In C++ worden slimme aanwijzers geïmplementeerd als sjabloonklassen die een aanwijzer inkapselen en standaardaanwijzeroperators overschrijven. Ze hebben een aantal voordelen ten opzichte van reguliere pointers. Ze worden gegarandeerd geïnitialiseerd als null-pointers of als pointers naar een heap-object. Indirectie via een null-pointer wordt gecontroleerd. Verwijderen is nooit nodig. Objecten worden automatisch vrijgegeven wanneer de laatste aanwijzer naar hen is verdwenen. Een belangrijk probleem met deze slimme wijzers is dat ze, in tegenstelling tot gewone wijzers, geen rekening houden met overerving. Slimme aanwijzers zijn onaantrekkelijk voor polymorfe code. Hieronder vindt u een voorbeeld voor de implementatie van slimme aanwijzers.

Voorbeeld:

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:
               //...
};

Deze klasse implementeert een slimme aanwijzer naar een object van het type X. Het object zelf bevindt zich op de heap. Hier is hoe het te gebruiken:

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

Net als andere overbelaste operators, gedraagt p zich als een gewone aanwijzer,

cout<<*p;
p->raise_salary(0.5);

Antwoord 9

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

In de informatica, een slimme aanwijzer
is een abstract gegevenstype dat
simuleert een aanwijzer tijdens het verstrekken van
extra functies, zoals automatische
vuilnisophaling of grenscontrole.
Deze extra functies zijn bedoeld
om bugs te verminderen die worden veroorzaakt door het misbruik van
aanwijzingen met behoud van efficiëntie.
Slimme aanwijzers houden meestal bij:
de objecten die ernaar verwijzen voor de
doel van geheugenbeheer. De
misbruik van pointers is een belangrijke bron
van bugs: de constante toewijzing,
deallocatie en verwijzingen die moeten
worden uitgevoerd door een programma geschreven
het gebruik van aanwijzers maakt het zeer waarschijnlijk
dat er geheugenlekken zullen optreden.
Slimme aanwijzers proberen geheugen te voorkomen
lekken door het maken van de bron
deallocation automatisch: wanneer de
aanwijzer naar een object (of de laatste in a
reeks aanwijzers) wordt vernietigd, voor
bijvoorbeeld omdat het buiten de scope valt,
het puntige object wordt ook vernietigd.


Antwoord 10

Laat T een klas zijn in deze tutorial
Pointers in C++ kunnen worden onderverdeeld in 3 typen:

1) Onbewerkte aanwijzingen:

T a;  
T * _ptr = &a; 

Ze houden een geheugenadres vast op een locatie in het geheugen. Wees voorzichtig bij het gebruik, omdat programma’s complex worden en moeilijk bij te houden zijn.

Aanwijzers met const-gegevens of adres { Achterwaarts lezen }

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

Aanwijzer naar een gegevenstype T dat een const is. Dit betekent dat u het gegevenstype niet kunt wijzigen met de aanwijzer. dat wil zeggen *ptr1 = 19; zal niet werken. Maar u kunt de aanwijzer verplaatsen. dat wil zeggen ptr1++ , ptr1--; enz. zal werken.
Achterwaarts lezen: aanwijzer naar type T, wat const is

 T * const ptr2 ;

Een const-pointer naar een gegevenstype T . Dit betekent dat u de aanwijzer niet kunt verplaatsen, maar dat u de waarde waarnaar de aanwijzer verwijst, kunt wijzigen. dwz *ptr2 = 19zal werken, maar ptr2++ ; ptr2--enz. zal niet werken. Achterwaarts lezen: const pointer naar een type T

const T * const ptr3 ; 

Een const-pointer naar een const-gegevenstype T . Dit betekent dat u de aanwijzer niet kunt verplaatsen en ook niet de aanwijzer van het gegevenstype kunt wijzigen als aanwijzer. dwz. ptr3-- ; ptr3++ ; *ptr3 = 19;werkt niet

3) Slimme aanwijzers: { #include <memory>}

Gedeelde aanwijzer:

 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

Geïmplementeerd met behulp van referentietelling om bij te houden hoeveel ‘dingen’ naar het object wijzen waarnaar de aanwijzer verwijst. Wanneer dit aantal naar 0 gaat, wordt het object automatisch verwijderd, dwz het bezwaar wordt verwijderd wanneer alle share_ptr die naar het object wijst, buiten het bereik valt.
Dit neemt de hoofdpijn weg van het moeten verwijderen van objecten die u met nieuw hebt toegewezen.

Zwakke aanwijzer :
Helpt bij het omgaan met cyclische verwijzingen die optreden bij het gebruik van Shared Pointer
Als u twee objecten hebt waarnaar wordt verwezen door twee gedeelde aanwijzers en er is een interne gedeelde aanwijzer die naar elkaars gedeelde aanwijzer wijst, dan is er een cyclische verwijzing en wordt het object niet verwijderd wanneer gedeelde aanwijzers buiten het bereik vallen. Om dit op te lossen, wijzigt u het interne lid van een shared_ptr in zwakke_ptr. Opmerking: om toegang te krijgen tot het element waarnaar wordt verwezen door een zwakke aanwijzer, gebruik lock() , dit retourneert een zwakke_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

Zie: Wanneer is std::weak_ptr nuttig?

Unieke aanwijzer :
Lichtgewicht slimme aanwijzer met exclusief eigendom. Gebruik wanneer de aanwijzer naar unieke objecten wijst zonder de objecten tussen de aanwijzers te delen.

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 

Gebruik move-semantiek om het object waarnaar wordt verwezen door de unieke ptr te wijzigen

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 

Referenties:
Ze kunnen in wezen worden beschouwd als const-wijzers, dat wil zeggen een aanwijzer die const is en niet kan worden verplaatst met een betere syntaxis.

Zie: Wat zijn de verschillen tussen een pointervariabele en een referentievariabele in 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 

Referentie:
https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ
Met dank aan Andre voor het wijzen op deze vraag.


Antwoord 11

Een slimme aanwijzer is een klasse, een wrapper van een normale aanwijzer. In tegenstelling tot normale aanwijzers, is de levenscirkel van slimme punten gebaseerd op een referentietelling (hoe vaak het slimme aanwijzerobject is toegewezen). Dus wanneer een slimme aanwijzer aan een andere wordt toegewezen, telt de interne referentie plus plus. En wanneer het object buiten bereik gaat, wordt het aantal referenties minus minus.

Automatische aanwijzer lijkt op elkaar, maar is totaal anders dan slimme aanwijzer. Het is een handige klasse die de toewijzing van de resource ongedaan maakt wanneer een automatisch aanwijzerobject buiten het variabele bereik gaat. Tot op zekere hoogte zorgt het ervoor dat een pointer (naar dynamisch toegewezen geheugen) vergelijkbaar is met een stackvariabele (statisch toegewezen in compileertijd).


Antwoord 12

Wat is een slimme aanwijzer.

Lange versie, In principe:

https://web .stanford.edu/class/archive/cs/cs106l/cs106l.1192/lectures/lecture15/15_RAII.pdf

Een modern C++-idioom:

RAII: Resource Acquisition Is Initialization.
● When you initialize an object, it should already have 
  acquired any resources it needs (in the constructor).
● When an object goes out of scope, it should release every 
  resource it is using (using the destructor).

belangrijkste punt:

● There should never be a half-ready or half-dead object.
● When an object is created, it should be in a ready state.
● When an object goes out of scope, it should release its resources. 
● The user shouldn’t have to do anything more. 

Onbewerkte pointers schenden RAII: de gebruiker moet deze handmatig verwijderen wanneer de pointers buiten het bereik vallen.

RAII-oplossing is:

Have a smart pointer class:
● Allocates the memory when initialized
● Frees the memory when destructor is called
● Allows access to underlying pointer

Voor een slimme aanwijzer die moet worden gekopieerd en gedeeld, gebruikt u shared_ptr:

● use another memory to store Reference counting and shared.
● increment when copy, decrement when destructor.
● delete memory when Reference counting is 0. 
  also delete memory that store Reference counting.

gebruik voor een slimme aanwijzer die niet de onbewerkte aanwijzer is, zwakke_ptr:

● not change Reference counting.

shared_ptr gebruik:

correct way:
std::shared_ptr<T> t1 = std::make_shared<T>(TArgs);
std::shared_ptr<T> t2 = std::shared_ptr<T>(new T(Targs));
wrong way:
T* pt = new T(TArgs); // never exposure the raw pointer
shared_ptr<T> t1 = shared_ptr<T>(pt);
shared_ptr<T> t2 = shared_ptr<T>(pt);

Vermijd altijd het gebruik van onbewerkte aanwijzer.

Voor scenario’s die een onbewerkte aanwijzer moeten gebruiken:

https://stackoverflow.com/a/19432062/2482283

Gebruik in plaats daarvan referentie voor onbewerkte aanwijzer die niet nullptr is.

not use T*
use T&  

Voor optionele referentie, die misschien nullptr is, gebruik de ruwe aanwijzer, en wat betekent:

T* pt; is optional reference and maybe nullptr.
Not own the raw pointer, 
Raw pointer is managed by some one else.
I only know that the caller is sure it is not released now.

Antwoord 13

Slimme aanwijzers zijn die waarmee u zich geen zorgen hoeft te maken over geheugentoewijzing, het delen van bronnen en overdracht.

Je kunt deze aanwijzer heel goed op dezelfde manier gebruiken als elke toewijzing in Java werkt. In Java doet Garbage Collector de truc, terwijl in Smart Pointers de truc wordt gedaan door Destructors.


Antwoord 14

De bestaande antwoorden zijn goed, maar beschrijven niet wat u moet doen als een slimme aanwijzer niet het (volledige) antwoord is op het probleem dat u probeert op te lossen.

Onder andere (goed uitgelegd in andere antwoorden) is het gebruik van een slimme aanwijzer een mogelijke oplossing voor Hoe gebruiken we een abstracte klasse als een functieretourtype?die is gemarkeerd als een duplicaat van deze vraag. De eerste vraag die je moet stellen als je in de verleiding komt om een abstracte (of eigenlijk elke) basisklasse op te geven als een retourtype in C++, is “wat bedoel je echt?”. Er is een goede discussie (met verdere referenties) van idiomatisch objectgeoriënteerd programmeren in C++ (en hoe dit verschilt van andere talen) in de documentatie van de boost pointer-containerbibliotheek. Kortom, in C++ moet je nadenken over eigendom. Welke slimme pointers helpen je, maar zijn niet de enige oplossing, of altijd een complete oplossing (ze geven je geen polymorfe kopie) en zijn niet altijd een oplossing die je in je interface wilt laten zien (en een functieretour klinkt vreselijk veel als een interface). Het kan bijvoorbeeld voldoende zijn om een referentie terug te sturen. Maar in al deze gevallen (slimme aanwijzer, aanwijzercontainer of simpelweg het retourneren van een referentie) heb je de terugkeer gewijzigd van een waardein een of andere vorm van verwijzing. Als je echt een kopie nodig hebt, moet je misschien meer standaard “idioom” toevoegen of verder gaan dan idiomatische (of anderszins) OOP in C++ naar meer generiek polymorfisme met behulp van bibliotheken zoals Adobe Polyof Boost.TypeErasure.

Other episodes