2015-09-02 20 views
16
#include <stdio.h> 

class C 
{ 
    public: 
      static int i; 
      static int j; 
}; 

int i = 10; 
int C::i = 20; 
int C::j = i + 1; 

int main() 
{ 
    printf("%d", C::j); 

    return 0; 
} 

Qual è il valore di: C :: jVariabili statiche di inizializzazione Quiz

Stavo leggendo un quiz ++ c e sono imbattuto alla seguente domanda. Ho pensato che la risposta fosse 11.

int C::j = i + 1;

Poiché si accede al i non statica che è 10? Quindi, ho pensato che 11 dovrebbe essere la risposta?

Ho compilato e eseguito questo codice tramite Visual Studio e stampa 21. Ciò mi confonde. Qualcuno può spiegare perché questo sta accadendo? Cosa mi manca?

+0

Uno dei motivi per cui odio C++. In un "mondo ideale", se dici "io", ottieni "io". Invece del linguaggio stupido che indovina e ti dà invece "C :: i". Credo che la soluzione alternativa - se si desidera "10" - è qualificare 'int C :: j = :: i + 1;'. – paulsm4

+1

Sì, sapevo che avrei potuto usare :: i per essere esplicito ma non pensavo di averne bisogno. – marsh

+6

La lingua non è una seconda ipotesi. Questo comportamento è uguale al comportamento di definire funzioni fuori linea. All'interno del corpo di una funzione di 'C' non vorresti digitare' C :: i' ogni volta che intendi il membro, vero? – Brian

risposta

23

[basic.lookup.qual]/3

In una dichiarazione in cui il dichiaratore-id è un qualificato-ID, nomi utilizzati prima della qualificata id essere dichiarati sono ricercati nello scope namespace definente; i nomi che seguono lo id qualificato vengono ricercati nell'ambito della classe o dello spazio dei nomi del membro.

In

int C::j = i + 1; 

il dichiaratore-id,cioè il nome dell'entità dichiarato, è C::j, che è un qualificata id. Pertanto, lo i seguente viene cercato nell'ambito di C e fa riferimento a C::i.

Meno tecnicamente, quando si definisce un membro di dati statici, l'inizializzatore può essere considerato nell'ambito della classe e troverà i membri della classe prima dei globali.

Questa è la stessa regola che assicura che quando si definisce una funzione di membro out-of-line, i nomi dopo il nome della funzione sarà guardato in ambito di classe e non richiederà la qualificazione esplicita se si riferiscono alla classe membri. È più insolito vedere questo essere applicato a definizioni di membri di dati statici, ma è perfettamente coerente.

+2

Probabilmente dovresti aggiungere il motivo per cui 'C :: j' necessariamente viene inizializzato dopo' C :: i', quindi è sicuramente 21 e non 1. – Barry

Problemi correlati