Domanda

Nel mio progetto in corso che sto usando boost::shared_ptr abbastanza ampiamente.

Di recente i miei compagni di squadra compagni hanno anche iniziato a utilizzare weak_ptr. Non so quale usare e quando.

Oltre a questo, che cosa devo fare se voglio convertire weak_ptr a shared_ptr. Non mettere un lucchetto sul weak_ptr per creare un effetto shared_ptr mio codice in altro thread?

È stato utile?

Soluzione

In generale e sintesi,

puntatori Forti garantire la propria validità. Usali, per esempio, quando:

  • Già l'oggetto puntato contro; si crea e distruggerlo
  • Se associ definito comportamento se l'oggetto non esiste
  • È necessario far rispettare ciò che esiste l'oggetto.

puntatori deboli garanzia di sapendo la propria validità. Usali, per esempio, quando:

  • Vi si accede, ma non è la tua.
  • È stato definito il comportamento se l'oggetto non esiste

Lock () su un puntatore debole restituisce un forte puntatore; in questo modo si accede al puntatore deboli. Se l'oggetto non è più valido (è stato cancellato, ecc), quindi il puntatore forte sarà nullo, in caso contrario, si punterà sulla proprietà. Sarà necessario controllare questo.

E 'impostato in questo modo in modo che non si può eliminare accidentalmente l'oggetto mentre si sta utilizzando, perché hai fatto un temporaneo (locale) forte puntatore, e quindi garunteed l'esistenza dell'oggetto mentre quella forte puntatore rimane. Quando hai finito con l'oggetto, in genere si lascia che la forte puntatore caduta fuori del campo di applicazione (o riassegnandolo), che poi consente l'oggetto da eliminare. Per il multithreading, trattarli con stessa cura si trattano le altre cose che non sono dotati di sicurezza dei thread, notando che la garanzia che ho citato sopra si tenere quando multithreading. Per quanto ne so non fanno nulla di speciale passato che.

I puntatori Boost condiviso hanno anche garbage-collector come le caratteristiche, dal momento che quando l'ultimo forte puntatore ad un oggetto va via o punti da qualche altra parte, l'oggetto viene eliminato.

C'è anche le prestazioni e le dipendenze circolari di cui le altre risposte.

Fondamentalmente, direi che la spinta libreria condivisa puntatore consenta di non rovinare mettere insieme un programma, ma non è un sostituto per il tempo per progettare correttamente i puntatori, proprietà di oggetti e vite. Se si dispone di un tale progetto, è possibile utilizzare la libreria di farla rispettare. Se non si dispone di un tale progetto, è molto probabile che incorrere in diversi problemi di prima.

Altri suggerimenti

Usa weak_ptr quando gli oggetti creati contengono riferimenti ciclici, vale a dire shared_ptr ad un oggetto con un shared_ptr a te stesso. Questo perché shared_ptr non può gestire i riferimenti ciclici - quando entrambi gli oggetti escono del campo di applicazione, il riferimento reciproco significa che essi non sono "garbage collection", così la memoria si perde e si dispone di una perdita di memoria. Poiché weak_ptr non aumenta il conteggio di riferimento, il problema di riferimento ciclico non si verifica. Questo significa anche, in generale, che, se si vuole solo prendere un puntatore a qualcosa che è contato di riferimento e non vogliono aumentare il conteggio dei riferimenti, quindi utilizzare weak_ptr.

In caso contrario, è possibile utilizzare shared_ptr.

Per ulteriori informazioni, controllare il Boost documentazione .

puntatori condivisi implementare il conteggio dei riferimenti, puntatori deboli non influenzano il conteggio dei riferimenti e se non si hanno i puntatori condiviso a un oggetto, puntatori solo deboli, l'oggetto viene eliminato ed i puntatori deboli ora ti dicono che l'oggetto è stato perso .

Ci sono due ragioni per usare un puntatore debole:

  1. Per eliminare il costo del conteggio dei riferimenti aumento / diminuzione; tuttavia, non si dovrebbe fare questo perché è soggetto a errori e in realtà non risparmiare molto tempo
  2. In strutture di dati, ad esempio si dispone di un indice di tutti gli oggetti Foo che sono "vivi", vale a dire utilizzati da qualche altra parte, e non si desidera mantenere un Foo viva nell'indice se tutti gli usi "reali" sono finiti. Questo è il caso d'uso realistico di base per i puntatori deboli. Naturalmente esistono anche altri.

Quindi, in generale, la mia raccomandazione sarebbe quella di utilizzare i puntatori deboli solo quando si sa che si desidera lasciare che gli oggetti cui si fa riferimento da cancellare e vogliono rilevare questo. In altri casi utilizzare puntatori condivisi (conteggio di riferimento), o puntatori diretti, esp. in variabili locali di metodo quando si sa che gli oggetti non stanno andando per essere cancellato. Inoltre errorprone, però, ma più veloce di puntatori condivisa.

NB. oggetti ciclici non hanno bisogno di puntatori deboli, è possibile utilizzare non cotte, puntatori regolari invece nella maggior parte dei programmi adeguatamente costruiti. puntatori deboli meno rischioso, però.

Si dovrebbe probabilmente non sta tentando di usare puntatori deboli a tutti a meno che non si sta cercando di implementare un garbage collector, che non è un'idea caldo in C ++ perché è troppo difficile tenere traccia di tutto ciò che poteva andare storto abbastanza da vicino.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top