2014-11-21 11 views

risposta

7

Sono garantiti per essere creati prima di qualsiasi oggetto statico dichiarato dopo aver incluso <iostream> e, in ogni caso, prima di iniziare main. Non vengono distrutti durante l'esecuzione del programma.

L'inclusione dell'intestazione ha l'effetto di dichiarare una variabile statica di tipo ios_base::Init, la cui creazione garantisce l'inizializzazione degli stream standard.

Se si desidera che lo Standardese per questo:

C++ 11 27.4.1 [iostream.objects.overview]/2: Gli oggetti sono costruiti e le associazioni sono stabiliti in un qualche momento prima o durante la prima volta viene costruito un oggetto della classe ios_base::Init, e in ogni caso prima che il corpo principale inizi l'esecuzione. Gli oggetti non vengono distrutti durante l'esecuzione del programma. I risultati dell'inserimento di <iostream> in un'unità di traduzione devono essere come se l'<iostream> definisse un'istanza di ios_base::Init con durata di archiviazione statica. Allo stesso modo, l'intero programma si comporterà come se ci fosse almeno un'istanza di ios_base::Init con durata di archiviazione statica.

+0

"main" non è l'unica cosa, un programmatore dovrebbe scrivere. Globali e statici sono anche candidati. – Ajay

+0

@ Ajay: In effetti, ecco perché "main" non è l'unica cosa che ho menzionato. Come ho detto, gli stream sono garantiti per essere creati prima di qualsiasi oggetto statico dichiarato dopo aver incluso ''. –

+0

Non sto dicendo che ti sbagli Mike, ma dubito. Perché: potrei avere più intestazioni, incluse nella sequenza corretta (o meno). Non vi è alcuna garanzia che le prime intestazioni verranno inserite nella fase di inizializzazione del linker/loader in quella determinata sequenza. O c'è garanzia? Se no, l'inclusione di "" non è altro che inclusione di testo. Sì, sono consapevole che il codice effettivo della classe stream risiede nella libreria di runtime (DLL, SO o static-lib). In questo caso, è garantito che gli oggetti DLL/SO/LIB vengano inizializzati per primi? Di nuovo, qual è la garanzia di ordine lì? – Ajay

7

La semplice risposta alla tua domanda è no. Come altri hanno sottolineato, sono garanzie per gli oggetti definiti nelle unità di traduzione compreso <iostream>, almeno se l'oggetto è definito dopo l'inclusione di . Ma questo non sempre aiuta: si include <iostream> in l'unità di traduzione che definisce il costruttore, non necessariamente in quello che definisce la variabile statica. Così casi come il seguente sono possibili:

file1.hh

class X 
{ 
public: 
    X(); 
}; 

file1.cc

#include "file1.hh" 
#include <iostream> 

X::X() 
{ 
    std::cout << "Coucou, me voila!" << std::endl; 
} 

file2.cc

#include "file1.hh" 

X anX; 

In questo caso, è molto probabile che il costruttore di anX sia chiamato prima std::cout è costruito.

Per essere sul sicuro: se il costruttore di un oggetto che potrebbe essere usato come una variabile statica vuole utilizzare uno dei flussi standard, si probabilmente dovrebbe dichiarare una statica locale di tipo ios_base::Init:

X::X() 
{ 
    static ios_base::Init dummyForInitialization; 
    std::cout << "Coucou, me voila!" << std::endl; 
} 

Se non è già stato creato quando questo costruttore è chiamato, sarà quando viene creata la variabile statica.

+0

Grazie per l'utile esempio "fingere" di essere cout/cin safe :) – hauron

+0

** + 1 ** per contro-esempio. –

+0

Questa risposta da un punto di vista pratico è più utile: mostra un esempio e come risolvere il problema. La domanda è stata posta sullo standard, ma credo che le risposte insieme costituiscano "la risposta perfetta", quindi ho scelto la risposta di Mike e ho votato a favore. – hauron

Problemi correlati