2012-12-25 24 views
6

Ho una semplice domanda niubbo che non riesco a trovare una risposta a:Converti oggetto di std :: unique_ptr

In C++ come si fa a convertire un oggetto regolare

int i; 

in un std::unique_ptr?

std::unique_ptr<int> iptr = &i; //invalid 
std::unique_ptr<int> iptr = static_cast<std::unique_ptr<int>>(&i); //invalid 

Grazie.

risposta

11

Non è così. Questo oggetto non può essere cancellato da delete, che è ciò che sta facendo il unique_ptr. È necessario

auto iptr = make_unique<int>(); 

Qui, definiamo make_unique come una funzione di utilità identico a make_shared, che avrebbe dovuto essere standard, ma purtroppo è stato trascurato. Ecco l'implementazione in breve:

template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) { 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 
+0

Anche se per completezza, la funzione sarebbe buona, ma non penso che sia stata trascurata per quanto non necessaria. Ricorda che make_shared risolve un problema di allocazione di due oggetti contemporaneamente (non esiste un costruttore equivalente), mentre unique_ptr semplicemente non ha bisogno di questo (non ha overhead di progetto). –

+0

Non è vero. Esiste ancora un'eccezione alla sicurezza se si costruiscono due unique_ptrs in una chiamata di funzione, ad esempio, che salva_unico salva. – Puppy

+0

Non puoi evitarlo creando l'unique_ptr direttamente in quel punto? 'func (unique_ptr (new T), unique_ptr (new U))' –

4

Non lo sai. i non è stato assegnato in modo dinamico, quindi non è necessario eliminarlo. Se hai avvolto un puntatore intelligente attorno al suo indirizzo, a un certo punto lo farebbe delete &i e ti darà un comportamento indefinito. Si dovrebbe avvolgere solo qualcosa che hai new ed in un puntatore intelligente, in questo modo:

std::unique_ptr<int> ptr(new int(5)); 

Il punto centrale di un puntatore intelligente è che gestisce il ciclo di vita di un oggetto allocato dinamicamente per voi. i ha una durata di archiviazione automatica, quindi verrà distrutto alla fine del suo ambito. Non hai bisogno di nulla per aiutarti con quello.

0

Quando unique_ptr verrà distrutto cosa accadrebbe? O al contrario, quando la variabile diventa fuori portata? Non ha senso in realtà

1

Credo che questo funzionerà:

int i; 
auto deleter = [](int *ptr){}; 
std::unique_ptr<int, decltype(deleter)> iptr(&i, deleter); 

È necessario fornire un deleter personalizzato che non fa nulla. Il delet predefinito non può cancellare una variabile automatica non allocata da new. (Tuttavia, ciò vanifica lo scopo di utilizzare un puntatore intelligente, ma mostra che è possibile).

Problemi correlati