1.x1 è solo una dichiarazione, non è vero? Quindi la sua definizione dovrebbe essere fatta in uno di quei file .cpp, giusto?
corretta
2.x2 è una definizione, giusto? Pensavo che static int sia anche una dichiarazione come extern int, ma ho sbagliato. x2 sarà visibile solo in a.h?
Un diverso x2
sarà disponibile in ogni unità di traduzione che include l'intestazione.
3.x3 sarà definito più volte se a.h è incluso in più file .cpp, quindi x3 comporterà l'errore di compilazione, giusto?
Più precisamente, si verificherà un errore del linker. Il compilatore elabora ogni unità di traduzione, il linker li unisce e rileva che il simbolo è definito più volte.
4.x4 è una definizione, giusto?
Sì, è una definizione, ma come x2
ciascuna unità di traduzione avrà il proprio x4
(sia per static
e poiché è const
che implica collegamento interno
5.Here in classe a, X5 è una dichiarazione, sì. Ma per quanto riguarda x4?
Sì, x5
è una dichiarazione solo (con l'inizializzazione). Il mig confusione Sorgono perché la parola chiave static
viene riutilizzata per significare cose diverse in diversi contesti. In x5
significa attributo della classe, mentre in x4
significa collegamento interno
Quest'ultimo caso è speciale. È l'unica dichiarazione (IIRC) in cui la dichiarazione può avere un valore e la ragione è che consente al compilatore di di utilizzare il il valore della costante in tutte le unità di traduzione che includono quell'intestazione come costante di tempo di compilazione . Se il valore doveva essere fornito con la definizione, solo una singola unità di traduzione avrebbe accesso a quel valore. La definizione di tale membro statico potrebbe essere:
const int A::x5; // no initialization here
ed è necessario fornire uno se il membro è ODR-usato. Ora il fatto è che nella maggior parte dei casi la costante non sarà odr-used in quanto il compilatore sostituirà il valore quando viene utilizzata l'espressione A::x5
. Solo quando il membro è utilizzato come lvalue è necessario alla definizione, ad esempio:
void f(const int &) {}
int main() {
f(A::x5);
}
Poiché l'argomento per f
è un riferimento, l'uso di A::x5
richiede un lvalue (nota, const-ness e lvalue/rvalue-ness sono quasi ortogonali) e ciò richiede la definizione del membro in una singola unità di traduzione nel tuo programma.
Cosa intendi con la domanda nel punto 5? –
@DavidHeffernan, intendo perché 'x5' è una dichiarazione ma' x4'? – Alcott