2013-06-25 10 views
11

Khi tôi viết đoạn mã sau nó được biên soạn và thực hiện đúng cách:Tại sao sử dụng chỉ thị hoạt động khác nhau trong phạm vi toàn cầu và phạm vi địa phương?

#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; 
} 

Nhưng nếu tôi viết sử dụng chỉ thị bên ngoài chức năng chính như sau,

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

Nó cho lỗi biên dịch này:

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 

Ai đó có thể giải thích lý do tại sao sử dụng chỉ thị hoạt động khác khi được sử dụng bên trong main và bên ngoài main?

Trả lời

10

Tuyên bố sử dụng chỉ là, một tuyên bố. Các using second::y; bên trong của chính là tương tự như tuyên bố một biến y trong phạm vi đó ẩn bất kỳ khác y s trong phạm vi không gian tên toàn cầu. Khi bạn sử dụng using second::y; trong phạm vi toàn cầu, bạn chưa ẩn bất kỳ tên nào vì cả hai số y đều nằm trong cùng một phạm vi.

Hãy tưởng tượng ví dụ đầu tiên của bạn là như sau (xin xem các ý kiến ​​dưới đây để giải thích):

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 
} 

Tuy nhiên, ví dụ thứ hai cũng giống như:

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

Cảm ơn Jesse đã trả lời nhanh ... Xin hãy sửa tôi nếu tôi sai ... Nhưng khi sử dụng chỉ thị có chức năng chính thì sẽ có 2 khai báo y. Nếu vậy tại sao trình biên dịch cho vấn đề trong trường hợp thứ hai chỉ? – Amrit

+1

@ user2235938: Có hai khai báo 'y', nhưng khai báo sử dụng khai báo' second :: y' bên trong chính, trong khi 'first :: y' được khai báo trong phạm vi không gian tên chung. Vì 'second :: y' được khai báo bên trong chính, nó ẩn' first :: y'. Bạn có quen với việc giấu tên không? –

+0

Xin lỗi Jesse ... Nhưng tôi không thể hiểu được. khi cả hai câu lệnh "sử dụng không gian tên trước tiên; sử dụng giây :: y;" nằm bên trong hàm main, nó sẽ khai báo cả hai :: y và second :: y trong phạm vi cục bộ và cung cấp lỗi biên dịch. Nhưng nó không và chương trình biên dịch và chạy thành công. Và khi cả hai câu lệnh đều nằm ngoài chính, nó thậm chí không được biên dịch do sự mơ hồ. Vui lòng giải thích ... – Amrit

6

Có hai sự khác biệt lớn giữa việc sử dụng khai báo và sử dụng chỉ thị.

Sự khác biệt đầu tiên: (Sự khác biệt rõ ràng).

namespace first{ 

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

này sẽ cho phép bạn sử dụng biến x mà không namespace tên như một vòng loại rõ ràng, và lưu ý rằng điều này không bao gồm y.

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

này sẽ cho phép bạn sử dụng tất cả các biến bên trong namespace first mà không namespace tên như một vòng loại rõ ràng.


Sự khác biệt thứ hai: (Đó là những gì bạn không hiểu).

Tôi sẽ giải thích cho bạn tại sao khi bạn sử dụng cả chỉ thị sử dụng và khai báo bên trong hàm chính, bạn sẽ không gặp lỗi, nhưng khi bạn cố gắng sử dụng cả hai trong không gian tên chung, bạn sẽ gặp phải lỗi biên dịch.

phép nói rằng chúng ta có hai không gian tên được định nghĩa trong namespace toàn cục như thế này:

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

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


Ví dụ 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; 
} 

Lý do là bằng cách sử dụng-chỉ using second::y sẽ biến biến số y của bạn trông giống như là biến cục bộ trong phạm vi nơi số using-directive là u sed, trong trường hợp này nó được sử dụng bên trong chức năng chính. Trong khi khai báo sử dụng using namespace first sẽ làm cho các biến được xác định bên trong không gian tên này first giống như chúng là các biến toàn cục và điều này chỉ hợp lệ trong phạm vi nơi sử dụng chỉ thị, trong trường hợp này nó nằm trong hàm chính.

vì vậy nếu bạn áp dụng what've nói ở trên, bạn sẽ biết rằng nếu bạn làm điều gì như thế này:

Ví dụ 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; 
} 

Bạn sẽ nhận được một lỗi, vì cả hai first::ysecond::y sẽ hoạt động như thể chúng đã được xác định trong không gian tên chung, vì vậy bạn sẽ kết thúc bằng việc phá vỡ Quy tắc Một Defintion.