using
編譯指令:它由名稱空間名和它前面的關鍵字 using namespace
組成,它使名稱空間中的所有名稱都可用,而不需要使用作用域解析運運算元。在全域性宣告區域中使用 using
編譯指令,將使該名稱空間的名稱全域性可用;在函數或程式碼塊中使用 using
編譯指令,將使其中的名稱在該函數或程式碼塊中可用。當包含 using
宣告的最小宣告區域中已經宣告了和名稱空間中相同的名稱時,若仍使用 using
宣告匯入該名稱空間的同名名稱,則這兩個名稱將會發生衝突,編譯器會報錯。與 using
宣告不同的是,using
編譯指令會進行名稱解析,在一些時候名稱空間的變數會被同區域宣告的同名變數隱藏,不會出現名稱衝突的報錯。但在另一些情況下,使用 using
編譯指令仍會出現名稱衝突的報錯,下面對此進行總結,測試所用的環境為 Microsoft Visual Studio 2019 以及 QT 5.9.2 MinGW 32bit。
結論:若僅存在同名全域性變數,不存在同名區域性變數,使用 using
編譯指令後,在作用域的重合區域使用變數時一定會引發名稱衝突。除非在同名全域性變數宣告前的程式碼塊中使用,但這時是因為同名變數的作用域不重合,而非 using
編譯指令名稱解析的功勞。
若在同名全域性變數宣告前的程式碼塊中使用,由於作用域不重合,一定不會引發名稱衝突,因此只需測試在同名全域性變數宣告前的全域性區中使用 using
編譯指令的效果。測試程式如下:(出現名稱衝突報錯)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//在同名全域性變數宣告前使用
using namespace Jack;
//在全域性名稱空間中定義變數
double pail = 2;
//測試
int main()
{
using namespace std;
//使用
cout << pail << endl;
cout << ::pail << endl;
cout << Jack::pail << endl;
return 0;
}
執行結果如下:
測試程式如下:(出現名稱衝突報錯)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//在全域性名稱空間中定義變數
double pail = 2;
//在同名全域性變數宣告後使用
using namespace Jack;
//測試
int main()
{
using namespace std;
//使用
cout << pail << endl;
cout << ::pail << endl;
cout << Jack::pail << endl;
return 0;
}
執行結果如下:
測試程式如下:(出現名稱衝突報錯)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//同名全域性變數宣告
double pail = 2;
//測試
int main()
{
using namespace std;
//使用
using namespace Jack;
cout << pail << endl;
cout << ::pail << endl;
cout << Jack::pail << endl;
return 0;
}
執行結果如下:
結論:若僅存在同名區域性變數,不存在同名全域性變數,使用 using
編譯指令將會進行名稱解析,不會引發名稱衝突,但在程式碼塊中,同名區域性變數將隱藏名稱空間中的變數。
測試程式如下:(執行成功)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//在同名區域性變數宣告前的全域性區中使用
using namespace Jack;
//測試
int main()
{
using namespace std;
//同名區域性變數
double pail = 2;
//使用
cout << pail << endl; //結果為2
cout << ::pail << endl; //結果為1
cout << Jack::pail << endl; //結果為1
return 0;
}
執行結果如下:
測試程式如下:(執行成功)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//測試
int main()
{
using namespace std;
//在同名區域性變數宣告前的程式碼塊中使用
using namespace Jack;
//同名區域性變數
double pail = 2;
//使用
cout << pail << endl; //結果為2
cout << Jack::pail << endl; //結果為1
return 0;
}
執行結果如下:
若在同名區域性變數宣告後的全域性區中使用,由於作用域不重合,一定不會引發名稱衝突,因此只需測試在同名區域性變數宣告後的程式碼塊中使用 using
編譯指令的效果。測試程式如下:(執行成功)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//測試
int main()
{
using namespace std;
//同名區域性變數
double pail = 2;
//在同名區域性變數宣告後的程式碼塊中使用
using namespace Jack;
//使用
cout << pail << endl; //結果為2
cout << Jack::pail << endl; //結果為1
return 0;
}
執行結果如下:
結論:若不同名稱空間中存在同名變數,不存在同名全域性變數以及同名區域性變數,使用 using
編譯指令後,在作用域的重合區域使用變數時一定會引發名稱衝突。
測試程式如下:(出現名稱衝突報錯)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
namespace Rose {
double pail = 2;
}
//都在全域性區中
using namespace Jack;
using namespace Rose;
//測試
int main()
{
using namespace std;
//使用
cout << pail << endl;
return 0;
}
執行結果如下:
測試程式如下:(出現名稱衝突報錯)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
namespace Rose {
double pail = 2;
}
//測試
int main()
{
using namespace std;
//都在程式碼塊中
using namespace Jack;
using namespace Rose;
//使用
cout << pail << endl;
return 0;
}
執行結果如下:
測試程式如下:(出現名稱衝突報錯)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
namespace Rose {
double pail = 2;
}
//Jack位於全域性區中
using namespace Jack;
//測試
int main()
{
using namespace std;
//Rose位於程式碼塊中
using namespace Rose;
//使用
cout << pail << endl;
return 0;
}
執行結果如下:
結論:若名稱空間中的變數、同名全域性變數、同名區域性區域性變數三者同時存在,using
編譯指令的使用位置不會影響名稱解析的結果,且不會引發名稱衝突,這正是 using
編譯指令進行名稱解析的效果。
測試程式如下:(執行成功)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//在同名全域性變數宣告前的全域性區中使用
using namespace Jack;
//同名全域性變數
double pail = 2;
//測試
int main()
{
using namespace std;
//同名區域性變數
double pail = 3;
//使用
cout << pail << endl; //結果為3
cout << ::pail << endl; //結果為2
cout << Jack::pail << endl; //結果為1
return 0;
}
執行結果如下:
測試程式如下:(執行成功)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//同名全域性變數
double pail = 2;
//在同名全域性變數宣告後的全域性區中使用
using namespace Jack;
//測試
int main()
{
using namespace std;
//同名區域性變數
double pail = 3;
//使用
cout << pail << endl; //結果為3
cout << ::pail << endl; //結果為2
cout << Jack::pail << endl; //結果為1
return 0;
}
執行結果如下:
測試程式如下:(執行成功)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//同名全域性變數
double pail = 2;
//測試
int main()
{
using namespace std;
//在同名區域性變數宣告前的程式碼塊中使用
using namespace Jack;
//同名區域性變數
double pail = 3;
//使用
cout << pail << endl; //結果為3
cout << ::pail << endl; //結果為2
cout << Jack::pail << endl; //結果為1
return 0;
}
執行結果如下:
測試程式如下:(執行成功)
#include <iostream>
//自定義名稱空間
namespace Jack {
double pail = 1;
}
//同名全域性變數
double pail = 2;
//測試
int main()
{
using namespace std;
//同名區域性變數
double pail = 3;
//在同名區域性變數宣告後的程式碼塊中使用
using namespace Jack;
//使用
cout << pail << endl; //結果為3
cout << ::pail << endl; //結果為2
cout << Jack::pail << endl; //結果為1
return 0;
}
執行結果如下:
通過上述多個測試,可以得到以下結論:
using
編譯指令後,在作用域的重合區域使用變數時一定會引發名稱衝突。using
編譯指令將會進行名稱解析,不會引發名稱衝突,但在程式碼塊中,同名區域性變數將隱藏名稱空間中的變數。using
編譯指令後,在作用域的重合區域使用變數時一定會引發名稱衝突。using
編譯指令的使用位置不會影響名稱解析的結果,且不會引發名稱衝突,這正是 using
編譯指令進行名稱解析的效果。以 Jack
名稱空間中的 pail
變數為例,將使用 using
編譯指令時可能遇到的各種情況列表如下,表中的最後一列是指在作用域的重合區域使用變數時是否會引發名稱衝突。
場景 | 同名全域性變數 pail |
同名區域性變數 pail |
另一名稱空間 Rose 的同名變數 pail |
using 編譯指令是否名稱衝突 |
---|---|---|---|---|
1 | 存在 | 無 | 無 | 衝突 |
2 | 存在 | 無 | 存在 | 衝突 |
3 | 無 | 存在 | 無 | 不衝突 |
4 | 無 | 存在 | 存在 | 不衝突 |
5 | 無 | 無 | 存在 | 衝突 |
6 | 存在 | 存在 | 無 | 不衝突 |
7 | 存在 | 存在 | 存在 | 不衝突 |
8 | 無 | 無 | 無 | 不衝突 |
本文作者:木三百川
本文連結:https://www.cnblogs.com/young520/p/16907603.html
版權宣告:本文系博主原創文章,著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請附上出處連結。遵循 署名-非商業性使用-相同方式共用 4.0 國際版 (CC BY-NC-SA 4.0) 版權協定。