2014-12-04 14 views
7

In generale non puntatori intelligenti quali std::unique_ptr e Glib::RefPtr eliminare il loro oggetto quando riassegnato a punto in un altro oggetto, dato che sono gli unici in possesso di puntatori che dato oggetto (ovviamente implicito in caso di std::unique_ptr)?Riassegnazione Puntatori Intelligente

risposta

9

Per unique_ptr::reset, [unique.ptr.single.modifiers]/4:

Effetti: assegna p al puntatore memorizzato, e quindi se il vecchio valore del puntatore memorizzato, old_p, non era uguale a nullptr, chiama get_deleter()(old_p).

oppure l'operatore di assegnazione mossa, operator=(unique_ptr&& u) in [unique.ptr.single.asgn]/2:

Trasferimenti di proprietà u-*this come se chiamando reset(u.release()) seguito da get_deleter() = std::forward<D>(u.get_deleter()).

(equivalente per l'altro modello di operatore di assegnazione)


Per shared_ptr, riassegnazione è un po 'diverso. shared_ptr non distruggerà mai un oggetto di riferimento quando non è l'ultimo che lo possiede, quindi supponiamo che sia dato.
shared_ptr::reset(Y*) specifica in [util.smartptr.shared.mod]/3:

Effetti: Equivalente a shared_ptr(p).swap(*this).

Ma chiaramente il temporaneo viene distrutto alla fine della chiamata di funzione, distruggendo l'oggetto di attesa (se applicabile).
Questo è lo stesso comportamento operator=(shared_ptr<> const&) ha, [util.smartptr.shared.assign]/1 e 4:

Effetti: Equivalente a shared_ptr(r).swap(*this).

... operatore di assegnazione mossa (template), r è shared_ptr<>&&:

Effetti: Equivalente a shared_ptr(std::move(r)).swap(*this).

Se *this era l'ultimo proprietario dell'oggetto, ora il temporaneo è - che verrà distrutto all'interno.


Per Glib::RefPtr lo scenario è simile a shared_ptr: L'operatore di assegnamento per copia (e un modello di operatore di assegnazione) sono definiti con la stessa semantica.Se l'attuale RefPtr è assegnato a qualcos'altro, il contatore di riferimento degli oggetti attualmente in attesa viene decrementato e viene distrutto se il valore del contatore risultante è zero.

+0

RefPtr something = getSomething(); something = getSomethingElse(); funziona bene. Non dovresti aver bisogno di usare RefPtr :: swap(). Ovviamente la riassegnazione qui diminuisce il riferimento sul primo Something piuttosto che cancellarlo. È un conteggio di riferimento _shared_ smartpointer. – murrayc

+0

@murrayc Devo aver letto male la documentazione la prima volta che ci sono passato. Grazie! – Columbo

3

Per unique_ptr la risposta è affermativa:

L'oggetto è distrutta e la sua memoria deallocato quando una delle seguenti accadere s: viene distrutto

  • unique_ptr la gestione dell'oggetto
  • unique_ptr gestione dell'oggetto viene assegnato un altro puntatore tramite operator = o reset().

L'oggetto viene distrutto utilizzando una delezione potenzialmente fornito dall'utente da chiamando Deleter (PTR). Il deleter chiama il distruttore dell'oggetto e distribuisce la memoria.