Perché `myvector.push_back (autoPtr.release ())` forniscono la forte garanzia di sicurezza eccezione?
-
26-09-2019 - |
Domanda
Modifica avrei dovuto detto, stavo guardando la documentazione per Boost ptr_sequence_adapter
e sostiene che il loro adattatore per il template< class U > void push_back( ::std::auto_ptr<U> x );
è equivalente a fare vec.push_back(autoPtr.release());
e fornisce anche la forte garanzia eccezione. E poi mi resi conto che era confusa la loro descrizione degli effetti della realizzazione di ciò che l'attuazione in realtà era, e così questa domanda è semi-senso. Sto lasciando qui per i posteri.
A me, sembra che la chiamata a std::auto_ptr<t>
avrebbe avuto successo, e poi la chiamata a std::vector<t*>::push_back
potrebbe generare un'eccezione, e il puntatore sarebbe trapelato.
Sembra che dovreste fare questo, invece:
vec.push_back(0); //Attempts to allocate space in vector, could throw bad_alloc
vec.back() = autoPtr.release(); //Provides nothrow
Soluzione
Questa è specificamente una caratteristica della biblioteca contenitori puntatore Boost.
La funzione di base membro push_back
è definito come:
void push_back( value_type x ) // strong
{
this->enforce_null_policy( x, "Null pointer in 'push_back()'" );
auto_type ptr( x ); // notrow
this->base().push_back( x ); // strong, commit
ptr.release(); // nothrow
}
(dal ptr_sequence_adapter.hpp intestazione )
Quindi, la funzione push_back
si prende la proprietà del puntatore e se riallocazione fallisce, si assume la responsabilità per la cancellazione del puntatore.
Il sovraccarico push_back
che accetta un auto_ptr
è definito in termini di funzione base push_back
:
template< class U >
void push_back( std::auto_ptr<U> x )
{
push_back( x.release() );
}
Il puntatore viene rilasciato prima della chiamata al push_back
base, che va bene perché la funzione di base push_back
ha una forte garanzia che cancellerà il puntatore se viene generata un'eccezione.
Altri suggerimenti
Trasferimento di un oggetto fuori di un auto_ptr stampa che il controllo di auto_ptr dell'oggetto. Non è più ottiene i benefici del auto_ptr. Si dovrà posizionare l'oggetto in un altro puntatore intelligente per diventare un'eccezione nuovo al sicuro, o di un oggetto contenitore che dà garanzie di sicurezza rispetto alle eccezioni (se ce ne sono?).
Si noti che std :: auto_ptr non può essere utilizzato direttamente in contenitori STL. Ad esempio, std :: vector