2011-06-12 19 views
18

Cancellare tipo: è così che si chiama?Scrittura di tipo in C++: come funzionano le funzioni boost :: shared_ptr e boost ::?

Come boost::shared_ptr memorizza il proprio deleter e in che modo boost::function memorizza il suo oggetto funzione?

C'è qualche tutorial che insegna il trucco?

Qual è il costo di runtime dell'utilizzo di oggetti funzione cancellati dal tipo?

+2

hai provato a google prima di chiedere? c'è un'infinità di informazioni sul web. il vecchio articolo di Thamas Becker: http://www.artima.com/cppsource/type_erasure.html o questo libro ben noto: http://www.boostpro.com/mplbook/ e molte altre risorse. –

+14

@GeneBushuyev: l'intero scopo di SO è fondamentalmente quello di rendere inutili le ricerche su Google. Se vuoi conoscere qualche argomento relativo alla programmazione, puoi farlo da Google e (1) trovare una risposta SO o (2) ottenere informazioni inaffidabili che potrebbero essere corrette o meno e aiutarti. Oppure puoi (2) cercare/chiederlo su SO, e ottenere risposte sottoposte a peer-review, classificate per qualità e virtualmente garantite come utili. Per favore non dirlo a Google, invece di fare domande qui. È controproducente. Il parametro – jalf

risposta

23

L'idea è semplice, si definisce una classe base che ha un'interfaccia con le funzionalità necessarie e quindi ne eredita. Poiché il tipo cancellato con la classe utilizza solo quell'interfaccia, il tipo effettivo sottostante è dimenticato e cancellato. In alternativa, se l'unica interfaccia necessaria può essere espressa come funzioni libere, è possibile memorizzare i puntatori alle funzioni libere.

namespace detail { 
    struct deleter_base { 
     virtual ~deleter_base() {} 
     virtual void operator()(void*) = 0; 
    }; 
    template <typename T> 
    struct deleter : deleter_base { 
     virtual void operator()(void* p) { 
     delete static_cast<T*>(p); 
     } 
    }; 
} 
template <typename T> 
class simple_ptr { 
    T* ptr; 
    detail::deleter_base* deleter; 
public: 
    template <typename U> 
    simple_ptr(U* p) { 
     ptr = p; 
     deleter = new detail::deleter<U>(); 
    } 
    ~simple_ptr() { 
     (*deleter)(ptr); 
     delete deleter; 
    } 
}; 

Questo è un puntatore intelligente davvero semplificato, ma l'idea è lì. Nel caso specifico di shared_ptr, il deletatore viene memorizzato come parte dell'oggetto conteggio di riferimento, che è trattenuto dal puntatore.

+0

shared_ptr non deve essere derivato da qualcosa. – pic11

+5

@ pic11: Il deleter passato a 'shared_ptr' non ha bisogno di ereditare, * ma * la cancellazione di tipo è implementata usando internamente l'ereditarietà (oi puntatori di funzione). –

+0

Come si chiama un oggetto funzione se non si conosce il suo tipo statico e/o non eredita da una classe base? – pic11

Problemi correlati