2013-05-04 20 views
10

In C++, static membri non può essere inizializzato nel corpo della classe con le seguenti eccezioni:In classe inizializzazione di membri dati statici

  • static membri const tipo integrale possono essere
  • static membri constexpr tipo letterale deve essere

Può spiegare perché questi ex percezioni?

Inoltre, questo vale:

Anche se un membro dati const static viene inizializzato nel corpo della classe, che ordinariamente membro dovrebbero essere definite all'esterno della definizione della classe.

Questo non l'ho mai capito. Qual è il punto di questa definizione in più?

Solo cercando di ottenere alcune intuizioni qui.

+2

Il punto chiave è se la variabile sarà o meno utilizzata. Finché non lo è, in realtà non è necessario definirlo, poiché è sufficiente incollare il suo * valore * ogni volta che si fa riferimento alla variabile. –

+3

Non è una definizione ** extra **; è una definizione. All'interno del corpo della classe hai una ** dichiarazione **. –

+1

Come si potrebbe desiderare di accedere al membro dei dati statici da diverse unità di traduzione (= file cpp), sarà necessario definire una "posizione" a cui fa riferimento ogni unità di traduzione, cioè una singola unità di traduzione in cui è definito il membro statico. È la stessa cosa delle variabili extern (globali). – dyp

risposta

6

Perché può esserci un inizializzatore nella definizione della classe?

quanto riguarda le due eccezioni per const e constexpr membri dati statici:

[class.static.data]/3

[Nota: In entrambi questi casi, l'elemento può apparire in espressioni costanti . - end note]

I.e. con un inizializzatore, puoi usarli in espressioni costanti, ad es.

struct s 
{ 
    static std::size_t const len = 10; 
    int arr[len]; 
}; 
std::size_t const s::len; 

Se len non è stata inizializzata nella definizione della classe, il compilatore non poteva facilmente conoscere il suo valore nella riga successiva per definire la lunghezza di arr.

Si potrebbe discutere consentendo inizializzatori per dei non const, non constexpr membri dati statici nella definizione della classe, ma questo potrebbe interferire con l'ordine di inizializzazione:

[basic.start.init]/2

Le definizioni di membri di dati statici di modelli di classe esplicitamente specializzati hanno ordinato l'inizializzazione. Altri membri di dati statici di modelli di classe (ovvero specializzazioni istanziate in modo implicito o esplicito) hanno un'inizializzazione non ordinata. Altre variabili non locali con durata di archiviazione statica hanno ordinato l'inizializzazione.

Cioè, l'ordine delle definizioni inclusi gli inizializzatori è importante. L'ordine di inizializzazione (dinamica) di oggetti non locali è definito solo all'interno di un'unità di traduzione, questo è un altro motivo per cui deve esserci una definizione che include l'inizializzatore per i membri di dati statici non , non constexpr.


Qual è il punto di questa definizione aggiuntiva?

Questo è già stato risposto nei commenti IMO. È possibile aggiungere l'ODR, ovvero come nome con collegamento esterno, il membro dei dati statici deve (solo) essere definito in un'unità di traduzione (se è utilizzato ODR). Spetta al programmatore scegliere questa unità di traduzione.

Problemi correlati