2013-04-18 15 views
10

Un collega ha insistito sull'uso di Meyer Singleton per tutte le variabili globali del puntatore come "non è garantito che la costruzione del globale unique_ptr non venga generata". Così, invece di:Quando sostituire uno std globale :: unique_ptr con un singleton

#include <memory> 

std::unique_ptr<Foo> ptr(nullptr); // Apparently this isn't safe. 

int main(/*blah*/) 
{ 
    ptr.reset(new Foo()); 
} 

Ora abbiamo

unique_ptr<Foo> singleton 
{ 
    try 
    { 
     static unique_ptr<Foo> ptr(); 
     return ptr; 
    } 
    catch (...) 
    { 
     std::cerr << "Failed to create single instance\n"; 
     exit(1); 
    } 
    return unique_ptr<Type>(); 
} 

int main() 
{ 
} 

A me questa sembra una soluzione in cerca di un problema. Ha un punto?

+1

Inoltre, direi che catturare l'eccezione, e quindi fare un'uscita (e buttare via ogni possibilità di capire perché ha fallito), sembra un'idea peggiore. La maggior parte dei sistemi, un'eccezione non gestita termina AND produce un output di debug (come un file core). –

risposta

21

Il tuo collega non è corretto (o forse è appena scaduto, le versioni pre-standard di unique_ptr potrebbero essere diverse). La nullptr_t costruttore unique_ptr è garantito non buttare (20.7.1.2):

constexpr unique_ptr (nullptr_t) noexcept : unique_ptr() {} 

Poiché è anche constexpr (e poiché nullptr è un'espressione costante), essa deve essere inizializzato durante l'inizializzazione costante (3.6.2/2). Quindi il controllo dell'ordine di inizializzazione (l'altro motivo per cui Meyers singleton potrebbe essere utile) non si applica anche qui.

+0

Tutti i "unique_ptr' ctors sono nient'altro. 'constexpr'ctor consente l'inizializzazione durante _constant initialization_, parte di _static initialization_, che viene eseguita prima di * any * _dynamic initialization_. – dyp

+0

@DyP: semplicemente consente o richiede? –

+1

Permette, ci sono ulteriori requisiti per l'init da eseguire durante _constant initialization_, vedere [basic.start.init]/2 – dyp

2

"non c'è garanzia la costruzione del unique_ptr globale non getterà"

E se si getta, cosa succede? L'applicazione viene terminata, sebbene lo standard non specifichi se lo stack viene svolto se non si rileva l'eccezione (come variabile globale, non c'è posto per rilevare l'eccezione). Non sono chiaro in che modo la soluzione proposta sia un chiaro miglioramento rispetto a ciò.

Problemi correlati