2013-06-25 9 views
11

Quando scrivo seguente codice che viene compilato ed eseguito correttamente:Perché l'uso della direttiva si comporta in modo diverso nell'ambito globale e nell'ambito locale?

#include <iostream> 
using namespace std; 

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

namespace second 
{ 
    double x = 3.1416; 
    double y = 2.7183; 
} 

int main() { 
    using namespace first; //using derective 
    using second::y; 
    cout << x << endl; 
    cout << y << endl; 
    return 0; 
} 

Ma se scrivo usando le direttive di fuori funzione principale come segue,

using namespace first; //using derective 
using second::y; 
int main() { 
    cout << x << endl; 
    cout << y << endl; 
    return 0; 
} 

Si dà questo errore di compilazione:

g++  namespace03.cpp -o namespace03 
namespace03.cpp: In function ‘int main()’: 
namespace03.cpp:20:11: error: reference to ‘y’ is ambiguous 
namespace03.cpp:13:10: error: candidates are: double second::y 
namespace03.cpp:7:7: error:     int first::y 
make: *** [namespace03] Error 1 

Qualcuno può spiegare perché l'uso della direttiva si comporta diversamente quando viene utilizzato all'interno di main e all'esterno dello main?

risposta

10

La dichiarazione di utilizzo è proprio questo, una dichiarazione. Lo using second::y; all'interno del main è simile alla dichiarazione di una variabile in quell'ambito che nasconde qualsiasi altro y s nello spazio dei nomi globale. Quando si utilizza using second::y; nell'ambito globale, non è stato nascosto alcun nome, poiché entrambi gli y sono nello stesso ambito.

Immaginate il vostro primo esempio è come il seguente (si vedano i commenti qui sotto per una spiegazione):

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

int main() { 
    using namespace first; // This makes first::y visible hereafter 
    int y = 20; // This hides first::y (similar to using second::y) 
    cout << x << endl; 
    cout << y << endl; // Prints 20 
} 

Tuttavia, il secondo esempio è simile:

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 
using namespace first; // This makes first::y visible in global scope 
int y = 20; // This is global ::y 
int main() { 
    cout << x << endl; 
    cout << y << endl; // Error! Do you mean ::y or first::y? 
} 
+0

Grazie Jesse per una rapida risposta ... Per favore correggimi se ho torto ... Ma quando si usano le direttive sono ancora nella funzione principale ci saranno 2 dichiarazioni di y. In tal caso, perché il compilatore dà problemi solo nel secondo caso? – Amrit

+1

@ user2235938: Esistono due dichiarazioni di 'y', ma la dichiarazione di utilizzo dichiara' second :: y' all'interno di main, mentre 'first :: y' è dichiarato nello scope namespace globale. Poiché 'second :: y' è dichiarato all'interno di main, nasconde' first :: y'. Hai familiarità con il nascondiglio del nome? –

+0

Scusa Jesse ... Ma non sono in grado di capire. quando entrambe le istruzioni "usano prima namespace; usando second :: y;" sono all'interno della funzione principale dovrebbe dichiarare sia first :: y che second :: y in ambito locale e dare errore di compilazione. Ma non funziona e programma la compilazione e funziona correttamente. E quando entrambe le affermazioni sono fuori lato, non vengono nemmeno compilate a causa dell'ambiguità. Spiega gentilmente ... – Amrit

6

ci sono due differenze importanti tra using-declaration e using-directive.

La prima differenza: (La differenza evidente).

namespace first{ 

int x=1; 
int y=2; 
} 
using first::x; //using declaration 

Questo vi permetterà di utilizzare la variabile x senza namespace nome- come un qualificatore esplicito, e si noti che questo non include y.

namespace first{ 
int x=1; 
int y=2; 
} 
using namespace first;// using directive 

Questo vi permetterà di utilizzare tutte le variabili all'interno del namespace first senza namespace nome- come un qualificatore esplicito.


La seconda differenza: (che è quello che non hai capito).

Vi spiegherò perché quando si utilizzano sia use-directive che using-declaration all'interno della funzione principale non si ottiene alcun errore, ma quando si tenta di utilizzarli entrambi nello spazio dei nomi globale si ottiene un errore in fase di compilazione.

Diciamo che abbiamo due namespace definito nel namespace globale come questo:

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

namespace second 
{ 
    double x = 3.1416; 
    double y = 2.7183; 
} 


Esempio 1:

int main() {  
using namespace first; 
using second::y; 
    cout << x << endl; // this will output first::x; 
    cout << y << endl; // this will output second::y; 
    return 0; 
} 

La ragione è che il using-directive using second::y renderà la tua variabile come se fosse una variabile locale per l'ambito in cui il using-directive è u sed, in questo caso è usato all'interno della funzione principale. Mentre la dichiarazione using using namespace first renderà le variabili che sono definite all'interno di questo spazio dei nomi first come se fossero variabili globali e questo è valido solo all'interno dell'ambito in cui è stata utilizzata la direttiva using, in questo caso è all'interno della funzione principale.

quindi se si applica Cos'hai detto sopra, si sa che se hai fatto qualcosa di simile:

Esempio 2:

using namespace first; 
using second::y; 

int main() {  
    cout << x << endl; 
    cout << y << endl; // two definitions of y. first::y and second::y 
    return 0; 
} 

Si otterrà un errore, dal momento che entrambi first::y e second::y si comporteranno come se fossero definiti nello spazio dei nomi globale, quindi finirai per rompere la regola di una definizione.

Problemi correlati