2012-05-24 22 views
8

Qual è l'obiettivo del puntatore con ambito? per quanto ne so, il puntatore scoped gestisce la memoria all'interno di un blocco di codice. Se voglio dichiarare una variabile all'interno di un blocco, posso semplicemente dichiararlo su una pila e non preoccuparmi della pulizia.Perché i puntatori con scope in boost

+0

http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm#Handle/Body –

risposta

1

Il punto è che è possibile creare e pulire un puntatore all'interno di un determinato ambito lessicale. Questo può essere utile in una varietà di situazioni e assicura che non ci siano perdite di memoria, dimenticando lo delete se si utilizza esplicitamente new, il che non è raccomandato.

si dovrebbe tenere a mente che il boost::scoped_ptr è non copiabile, e quindi possiede è risorsa del tutto, per tutta la durata della sua vita. Ciò inoltre rende più sicuro lo boost::shared_ptr, in quanto evita di copiare la risorsa o di condividerla accidentalmente.

{ //Some Scope 

    boost::scoped_ptr<int> i_ptr; 
    // do something with pointer 

} // leave scope, pointer is cleaned up 
4

Non se di dimensione o tipo dinamico. Inoltre, i puntatori con scope possono essere scambiati, e in C++ 11 unique_ptr possono essere spostati, quindi non sono strettamente ad ambito.

+1

Solo che "La ragione principale per usare 'scoped_ptr' piuttosto che' auto_ptr' è far sapere ai lettori del tuo codice che intendi "l'acquisizione delle risorse è inizializzata" da applicare solo per l'ambito corrente e non hai intenzione di trasferire la proprietà "... sembra come scambiare 'non è un uso previsto. –

+0

@BenVoigt: ma è fornito e può essere utilizzato. – Puppy

+2

Ecco [un vecchio thread] (http://lists.boost.org/Archives/boost/2002/09/36359.php) che spiega perché "swap" è diventato un requisito (in pratica si può usare "scoped_ptr" come membro di una classe copiabile). –

0

in genere gli stack di thread hanno limiti di memoria (vedere thread stacksize).

anche a volte il puntatore potrebbe essere stato passato dall'esterno e deve essere eliminato in questo ambito (ad esempio se viene lanciata un'eccezione, qualsiasi chiamata di cancellazione al di sotto di quella linea non verrà eseguita). Quindi è necessario in qualche modo di auto-magicamente ripulire il puntatore

void foo(Object*obj) 
{ 
    //this will ensure that object gets cleaned up even if doFoo() throws an exception 
    boost::scoped_ptr<Object> objCleaner(obj); 
    obj->doFoo(); 
} 
+0

Posso dichiarare il puntatore in pila e verrebbe automaticamente ripulito quando la funzione uscisse dall'ambito, con successo o tramite eccezione. Corretta? – Jimm

+0

{X * x = & someObj; } questo non farà sì che il puntatore x venga cancellato quando esce dal campo di applicazione. someObj verrà eliminato quando esce dall'ambito. {X * y = new X();} questo tipo di codice richiede scope ptr per la pulizia automatica – mohaps

2

A differenza dei dati basati sullo stack, scoped_ptr ha un membro di reset() - in altre parole, è possibile costruire/destruct al contenuto del vostro cuore. Con questo, è possibile utilizzare un puntatore nullo (tecnicamente operator unspecified-bool-type) come un indicatore che indica se esiste o meno un oggetto costruito in un dato momento. Permette anche di sequenziare costruzione/distruzione indipendentemente dall'ambito della variabile se necessario.

Inoltre, si consideri che è possibile dichiarare scoped_ptr come membro della classe, non solo come variabile di stack. Il docs suggerisce di utilizzare scoped_ptr per implementare l'handle/linguaggio del corpo (per nascondere i dettagli dell'implementazione della classe).

infine, di approfondire il punto di DeadMG "No, se è di tipo dinamico", è possibile utilizzare scoped_ptr per implementare un'operazione polymorphic:

{ 
scoped_ptr<Base> a(mode ? new DerivedA : new DerivedB); 
a->polymorphic_function(); 
} 

Non è davvero possibile fare questo con semplice stack- allocazione basata


vedi anche qui: C++0x unique_ptr replaces scoped_ptr taking ownership?

+0

'boost :: variant '. :) – GManNickG

+0

@GManNickG: Non penso che boost :: variant offra un buon rimpiazzo per il polimorfismo via scoped_ptr - comunque interessante. Grazie! – nobar

+0

Perché non la pensi così? – GManNickG