2010-09-22 11 views
8

Desidero un puntatore intelligente conteggiato senza riferimento che possa combinare alcuni degli aspetti utili di auto_ptr e shared_ptr. Penso che il C++ 0x unique_ptr sia in definitiva ciò di cui ho bisogno, ma ho bisogno di qualcosa che verrà compilato su Visual Studio 2008 e Xcode (gcc 4.2).C'è un puntatore intelligente generale come auto_ptr e shared_ptr che non ha bisogno di C++ 0x?

La funzionalità ho bisogno è:

  • Utilizzabile in metodi di fabbrica in modo che la proprietà viene trasferita sulla copia (come auto_ptr)
  • Supporta release() (come auto_ptr)
  • Può essere utilizzato con dichiarazione anticipata (like shared_ptr)

Quindi, suppongo che sia davvero meglio auto_ptr. C'è qualcosa che lo fa in boost o altrove (nota: non ho il tempo di girarmi intorno a Loki)? O dovrei semplicemente rotolare il mio?

EDIT: Ho appena letto di più su auto_ptr - suona come si può utilizzarlo con le dichiarazioni previsionali, se ci si assicura che l'intestazione di classe è incluso in ogni file cpp che fa riferimento l'intestazione con la smart puntatore (ad es. vedi GotW). Qualcuno ha qualche consiglio o regola generale su questo?

EDIT2: La ragione per cui shared_ptr non è accettabile è perché ho bisogno di un metodo release() poiché sto riordinando un codice legacy introducendo i metodi factory, ma deve coesistere con un codice di proprietà del puntatore manuale. L'utilizzo di shared_ptr in tutta la codebase sarebbe fantastico, ma un compito enorme.

EDIT3: Alla fine, auto_ptr è stato adeguato per il lavoro una volta che ho scoperto le stranezze dell'inclusione diretta. Sarebbe anche interessante provare a scrivere un deleter personalizzato per shared_ptr per consentire la cancellazione opzionale del puntatore.

+0

Questo è esattamente ciò che uso auto_ptr per. Fino a quando non ho iniziato a usare boost (o in situazioni in cui non posso usare boost). –

+0

Dai un'occhiata a https://github.com/codenrun/auto_ptr_custom. Aggiunge un deleter personalizzato a un'interfaccia come auto_ptr. – fizzbuzz

risposta

5

Modifica: Nella mia risposta originale, non sono riuscito a capire che boost::shared_ptr non è accettabile per voi (probabilmente per motivi di prestazioni).

auto_ptr fa, come si nota, la dichiarazione di supporto. È necessario includere l'intestazione della classe di riferimento in quelle posizioni che potrebbero distruggere l'oggetto a cui fa riferimento lo auto_ptr. Si noti, tuttavia, che la semantica di auto_ptr è leggermente particolare e richiede una certa attenzione.

Le risposte alla seguente domanda contiene ulteriori informazioni, tra cui il motivo per cui unique_ptr possono essere implementate solo per C++ 0x, perché richiede riferimenti rvalue:

unique_ptr boost equivalent?

+0

La ragione per cui 'shared_ptr' non è accettabile è perché ho bisogno di un metodo' release() 'dato che sto riordinando un codice legacy introducendo i metodi factory, ma deve coesistere con qualche codice di proprietà del puntatore manuale. L'uso di 'shared_ptr' in tutto il codebase sarebbe fantastico, ma un compito enorme. –

+0

@the_mandrill: non vedo come questo sia un problema. Boost consente di deleter personalizzati. Puoi scrivere un deleter personalizzato che è un no-op per i puntatori che hai pubblicato. – MSalters

+0

Se si scrive un deleter personalizzato non operativo, ciò non impedisce di rilasciare mai il puntatore? O intendi un deleter personalizzato in cui puoi commutarlo per eliminare/non cancellare in fase di runtime? –

2

C++ TR1 (supportati da moderno GCC e Visual Studio) ha incorporato shared_ptrand others (cf. Wikipedia). Queste sono state prese principalmente da Boost che funziona praticamente per qualsiasi compilatore moderno.

Se è necessaria una proprietà rigorosa, è possibile controllare lo scoped_ptr.

+0

non è un'opzione valida secondo il_mandrill. shared_ptr usa ref count e scoped_ptr non supporta release. – sellibitze

2

Con alcuni codici di codice è possibile unique_ptr in C++ 03. Non è un'emulazione perfetta.Avrai bisogno di un altro paio di chiamate esplicite move, ad esempio, per poter restituire un numero locale unique_ptr.

Problemi correlati