2010-09-02 13 views
13

qualcuno potrebbe riassumere in poche parole sintetiche come utilizzare il puntatore intelligente boost shared_from_this<>(), in particolare dal punto di vista della registrazione dei gestori nel io_service utilizzando la funzione bind.boost shared_from_this <>()

MODIFICA: alcune risposte hanno richiesto più contesto. Fondamentalmente, sto cercando "trucchi", comportamenti contro-intuitivi che le persone hanno osservato usando questo meccanismo.

+1

Che cosa esattamente non capisci? È difficile rispondere a una domanda non diretta. – GManNickG

+0

L'unico modo in cui potrei tentare di illustrare un esempio era incollare in risme di codice, che, essendo il codice boost, è abbastanza denso così com'è. –

risposta

30

Il più grande "trucco" che ho incontrato è che è illegale chiamare shared_from_this dal costruttore. Questo deriva direttamente dalla regola che deve esistere un shared_ptr per l'oggetto prima di poter chiamare shared_from_this.

+4

+1 buon consiglio, tipicamente fornisco il mio costruttore e fornisco un metodo 'shared_ptr statico'. –

+2

Penso che intendessi rendere privato il tuo costruttore. –

14

Dalla mia comprensione, a volte nel codice si desidera che una classe offra shared_ptr a se stessa in modo che altre parti del codice possano ottenere shared_ptr a un oggetto della classe dopo che è stato creato.

Il problema è che se la classe ha solo un valore shared_ptr<> come variabile membro, non verrà mai automaticamente distrutta, poiché c'è sempre "un ultimo riferimento" che gira su se stesso. L'ereditarietà di enable_shared_from_this fornisce alla classe un metodo automatico che non solo restituisce uno shared_ptr, ma mantiene solo un puntatore condiviso debole come variabile membro in modo da non influire sul conteggio dei riferimenti. In questo modo, la tua classe verrà liberata come al solito quando l'ultimo riferimento ad esso è andato.

Non l'ho mai usato, ma questa è la mia comprensione di come funziona.

8

shared_from_this<> viene utilizzato se un oggetto desidera accedere a un shared_ptr<> che punta a se stesso.

Solitamente un oggetto conosce solo il puntatore implicito this, ma non circa alcun shared_ptr<> che lo gestisce. Inoltre, non può essere convertito facilmente in un shared_ptr<> che condivide la proprietà con altre istanze esistenti shared_ptr<>, quindi non esiste un modo semplice per un oggetto per ottenere uno shared_ptr<> valido per se stesso.

shared_from_this<> può essere utilizzato per risolvere questo problema. Per esempio:

struct A : boost::enable_shared_from_this<A> { 
    server *io; 
    // ... 

    void register_self() { 
     io->add_client(shared_from_this()); 
    } 
}; 
5

la documentazione boost::asio::io_servicedestructor spiega abbastanza bene

La sequenza di distruzione descritto sopra permessi programmi per semplificare la gestione di risorse utilizzando shared_ptr <>. Dove vita di un oggetto è legata alla durata di una connessione (o qualche altra sequenza di operazioni asincrone ), uno shared_ptr all'oggetto sarebbe vincolato nelle gestori per tutte asincroni operazioni associate con esso. Questo funziona come segue:

  • Quando una singola connessione termina, tutte le operazioni asincrone associato completa. Gli oggetti corrispondenti sono stati distrutti e tutti i riferimenti shared_ptr agli oggetti vengono distrutti.
  • Per arrestare l'intero programma, la funzione io_service stop() viene chiamata per terminare qualsiasi chiamata run() il più presto possibile .Il distruttore io_service definito sopra distrugge tutti i gestori, causando tutti i riferimenti shared_ptr a tutti gli oggetti di connessione da distrutti.

Tipicamente gli oggetti verranno operazioni asincrone catena dove i gestori sono destinati a funzioni membro utilizzando boost::bind e boost::shared_from_this(). Ci sono alcuni examples che usano questo concetto.

+0

La tua risposta mi ha finalmente spiegato esempi asio ... In particolare, cosa succede se c'è un errore nella connessione e l'esempio del server http da asio. – Coyote21

Problemi correlati