2010-04-09 21 views

risposta

130

Ovunque nel un'unità compilazione (di solito un file cpp) farebbe:

foo.h

class foo { 
    static const string s; // Can never be initialized here. 
    static const char* cs; // Same with C strings. 

    static const int i = 3; // Integral types can be initialized here (*)... 
    static const int j; //  ... OR in cpp. 
}; 

foo.cpp

#include "foo.h" 
const string foo::s = "foo string"; 
const char* foo::cs = "foo C string"; 
// No definition for i. (*) 
const int foo::j = 4; 

(*) In base alle norme è necessario definire i al di fuori della definizione di classe (come j è) se viene utilizzato in codice diverso da espressioni costanti solo integrali . Vedi il commento di David sotto per i dettagli.

+21

Ho svitato, ma dopo aver esaminato lo standard c'è un errore nel codice: 'i' deve essere * definito * nel cpp. §9.4.2/4 * Se un membro di dati statici è di tipo const integrale o const enumeration, la sua dichiarazione nella definizione di classe può specificare un inizializzatore costante che deve essere un'espressione di costante integrale (5.19). In tal caso, il membro può apparire in espressioni costanti integrali. Il membro deve ancora essere definito in un ambito spazio dei nomi se viene utilizzato nel programma e la definizione dell'ambito dello spazio dei nomi non deve contenere un inizializzatore. * –

+3

In base alla citazione dagli standard, sembra che 'i' dovrebbe essere definito * solo * se è stato usato da qualche altra parte rispetto alle espressioni costanti integrali, giusto? In questo caso non si può dire che ci sia un errore perché non c'è abbastanza contesto per essere sicuri - o in senso stretto l'esempio sopra è corretto se non c'è altro codice. Ora apprezzo il tuo commento (+1), sto ancora imparando le cose da solo! Quindi cercherò di chiarire questo punto della risposta, per favore fatemi sapere se è meglio ... – squelart

+0

@squelart Scusa se suono stupido ma un esempio di istruzione diverso dall'espressione costante integrata sarebbe? – Saksham

8

In un'unità di traduzione all'interno dello stesso spazio dei nomi, di solito in alto:

// foo.h 
struct foo 
{ 
    static const std::string s; 
}; 

// foo.cpp 
const std::string foo::s = "thingadongdong"; // this is where it lives 

// bar.h 
namespace baz 
{ 
    struct bar 
    { 
     static const float f; 
    }; 
} 

// bar.cpp 
namespace baz 
{ 
    const float bar::f = 3.1415926535; 
} 
12

membri statici devono essere inizializzato in un'unità di traduzione cpp nell'ambito di file o nel dominio appropriato:

const string foo::s("my foo"); 
1

Solo i valori interi (ad es. static const int ARRAYSIZE) vengono inizializzati nel file di intestazione perché vengono solitamente utilizzati nell'intestazione della classe per definire qualcosa come la dimensione di un array. I valori non integrali sono inizializzati nel file di implementazione.

-1
const string foo::s("my foo"); 

E dovrebbe essere inizializzato nel file sorgente, altrimenti va male quando lo si invoca nel caso di test.

Problemi correlati