2013-06-15 13 views
9

Ho una libreria C su cui sto eseguendo il porting su C++ che fa un uso pesante delle strutture conteggiate manualmente. Ho considerato l'utilizzo di shared_ptr per gestire automaticamente il conteggio dei riferimenti, ma voglio anche mantenere l'API C. Le vecchie firme sembrano qualcosa di simile:Utilizzo di shared_ptr nelle interfacce C?

Object* object_create(void); 
Object* object_retain(Object* o); 
void object_release(Object* o); 

Se uso shared_ptr, c'è qualche modo per esporre in modo efficace questo conteggio dei riferimenti manuale in un API C?

+1

Giusto per chiarire; vuoi un shared_ptr per racchiudere un puntatore raw ottenuto da 'object_create', e chiamarlo' object_release' nel momento rilevante? –

+0

@OliCharlesworth No, sto reimplendendo 'Object' come una classe (invece che una struct) in C++, e sto usando' shared_ptr' all'interno del codice C++. Sono interessato se è possibile ottenere un puntatore raw da un shared_ptr e poi in qualche modo farlo funzionare con il conteggio di shared_ptr. –

+2

Potrebbe essere meglio usare [Boost.intrusive_ptr] (http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/intrusive_ptr.html). – Angew

risposta

5

Il problema con shared_ptr, come avrete già capito, è che non è possibile modificare il conteggio dei riferimenti tranne la costruzione o la distruzione di istanze. Quindi no, non c'è modo di farlo funzionare tranne mantenendo uno shared_ptr su ogni Object costruito fino a che il suo conteggio di riferimento non scende a zero, ma facendo ciò comporta il rifacimento di gran parte del conteggio dei riferimenti, quindi guadagni poco.

Forse boost::intrusive_ptr è un'opzione migliore.

1

È possibile utilizzare std::shared_ptr::get per recuperare il valore del puntatore nel proprio object_create.

Non sono sicuro di dover mantenere object_retain o object_release in quanto è già gestito automaticamente dallo shared_ptr.

Vuoi che la tua libreria sia utilizzata dal codice C? Se è così, come ha sottolineato @Angew nel suo commento, date un'occhiata a Boost.intrusive_ptr, sembra essere la scelta migliore.

Se si può assumere che il codice client scritto in C utilizzerà la libreria C (che credo abbia un senso), è possibile eliminare completamente queste funzioni e gestirle tutte internamente. È possibile fornire un puntatore raw per la compatibilità con C api se necessario, ma tutta la gestione della durata può essere gestita automaticamente con shared_ptr.

+0

Il conteggio dei riferimenti non viene mantenuto automaticamente sul lato C. Se l'ultimo 'shared_ptr' in un' Object' viene distrutto ma c'è ancora un 'Object *' che punta ad esso, l'oggetto viene distrutto e il puntatore C viene lasciato penzolare. –

+0

Vero, stavo pensando a un puntatore crudo usato come visualizzatore dell'oggetto, assumendo che 'shared_ptr' avrebbe gestito la vita dell'oggetto. – Uflex

Problemi correlati