C++?using?編譯指令與名稱沖突問題
using 編譯指令由名稱空間名和它前面的關(guān)鍵字 using namespace 組成,它使名稱空間中的所有名稱都可用,而不需要使用作用域解析運算符。與 using 聲明不同的是,using 編譯指令會進(jìn)行名稱解析,在一些時候名稱空間的變量會被同區(qū)域聲明的同名變量隱藏,不會出現(xiàn)名稱沖突的報錯。但在另一些情況下,使用 using 編譯指令仍會出現(xiàn)名稱沖突的報錯,下面對此進(jìn)行總結(jié)。
using
編譯指令:它由名稱空間名和它前面的關(guān)鍵字 using namespace
組成,它使名稱空間中的所有名稱都可用,而不需要使用作用域解析運算符。在全局聲明區(qū)域中使用 using
編譯指令,將使該名稱空間的名稱全局可用;在函數(shù)或代碼塊中使用 using
編譯指令,將使其中的名稱在該函數(shù)或代碼塊中可用。當(dāng)包含 using
聲明的最小聲明區(qū)域中已經(jīng)聲明了和名稱空間中相同的名稱時,若仍使用 using
聲明導(dǎo)入該名稱空間的同名名稱,則這兩個名稱將會發(fā)生沖突,編譯器會報錯。與 using
聲明不同的是,using
編譯指令會進(jìn)行名稱解析,在一些時候名稱空間的變量會被同區(qū)域聲明的同名變量隱藏,不會出現(xiàn)名稱沖突的報錯。但在另一些情況下,使用 using
編譯指令仍會出現(xiàn)名稱沖突的報錯,下面對此進(jìn)行總結(jié),測試所用的環(huán)境為 Microsoft Visual Studio 2019 以及 QT 5.9.2 MinGW 32bit。
1 using 編譯指令與同名全局變量
結(jié)論:若僅存在同名全局變量,不存在同名局部變量,使用 using
編譯指令后,在作用域的重合區(qū)域使用變量時一定會引發(fā)名稱沖突。除非在同名全局變量聲明前的代碼塊中使用,但這時是因為同名變量的作用域不重合,而非 using
編譯指令名稱解析的功勞。
1.1 在同名全局變量聲明前使用
若在同名全局變量聲明前的代碼塊中使用,由于作用域不重合,一定不會引發(fā)名稱沖突,因此只需測試在同名全局變量聲明前的全局區(qū)中使用 using
編譯指令的效果。測試程序如下:(出現(xiàn)名稱沖突報錯)
#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; }
運行結(jié)果如下:
1.2 在同名全局變量聲明后的全局區(qū)中使用
測試程序如下:(出現(xiàn)名稱沖突報錯)
#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; }
運行結(jié)果如下:
1.3 在同名全局變量聲明后的代碼塊中使用
測試程序如下:(出現(xiàn)名稱沖突報錯)
#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; }
運行結(jié)果如下:
2 using 編譯指令與同名局部變量
結(jié)論:若僅存在同名局部變量,不存在同名全局變量,使用 using
編譯指令將會進(jìn)行名稱解析,不會引發(fā)名稱沖突,但在代碼塊中,同名局部變量將隱藏名稱空間中的變量。
2.1 在同名局部變量聲明前的全局區(qū)中使用
測試程序如下:(運行成功)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } //在同名局部變量聲明前的全局區(qū)中使用 using namespace Jack; //測試 int main() { using namespace std; //同名局部變量 double pail = 2; //使用 cout << pail << endl; //結(jié)果為2 cout << ::pail << endl; //結(jié)果為1 cout << Jack::pail << endl; //結(jié)果為1 return 0; }
運行結(jié)果如下:
2.2 在同名局部變量聲明前的代碼塊中使用
測試程序如下:(運行成功)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } //測試 int main() { using namespace std; //在同名局部變量聲明前的代碼塊中使用 using namespace Jack; //同名局部變量 double pail = 2; //使用 cout << pail << endl; //結(jié)果為2 cout << Jack::pail << endl; //結(jié)果為1 return 0; }
運行結(jié)果如下:
2.3 在同名局部變量聲明后使用
若在同名局部變量聲明后的全局區(qū)中使用,由于作用域不重合,一定不會引發(fā)名稱沖突,因此只需測試在同名局部變量聲明后的代碼塊中使用 using
編譯指令的效果。測試程序如下:(運行成功)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } //測試 int main() { using namespace std; //同名局部變量 double pail = 2; //在同名局部變量聲明后的代碼塊中使用 using namespace Jack; //使用 cout << pail << endl; //結(jié)果為2 cout << Jack::pail << endl; //結(jié)果為1 return 0; }
運行結(jié)果如下:
3 不同名稱空間中的同名變量
結(jié)論:若不同名稱空間中存在同名變量,不存在同名全局變量以及同名局部變量,使用 using
編譯指令后,在作用域的重合區(qū)域使用變量時一定會引發(fā)名稱沖突。
3.1 using 編譯指令位置都在全局區(qū)中
測試程序如下:(出現(xiàn)名稱沖突報錯)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } namespace Rose { double pail = 2; } //都在全局區(qū)中 using namespace Jack; using namespace Rose; //測試 int main() { using namespace std; //使用 cout << pail << endl; return 0; }
運行結(jié)果如下:
3.2 using 編譯指令位置都在代碼塊中
測試程序如下:(出現(xiàn)名稱沖突報錯)
#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; }
運行結(jié)果如下:
3.3 using 編譯指令位置不同區(qū)
測試程序如下:(出現(xiàn)名稱沖突報錯)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } namespace Rose { double pail = 2; } //Jack位于全局區(qū)中 using namespace Jack; //測試 int main() { using namespace std; //Rose位于代碼塊中 using namespace Rose; //使用 cout << pail << endl; return 0; }
運行結(jié)果如下:
4 多個同名變量共存
結(jié)論:若名稱空間中的變量、同名全局變量、同名局部局部變量三者同時存在,using
編譯指令的使用位置不會影響名稱解析的結(jié)果,且不會引發(fā)名稱沖突,這正是 using
編譯指令進(jìn)行名稱解析的效果。
4.1 在同名全局變量聲明前的全局區(qū)中使用
測試程序如下:(運行成功)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } //在同名全局變量聲明前的全局區(qū)中使用 using namespace Jack; //同名全局變量 double pail = 2; //測試 int main() { using namespace std; //同名局部變量 double pail = 3; //使用 cout << pail << endl; //結(jié)果為3 cout << ::pail << endl; //結(jié)果為2 cout << Jack::pail << endl; //結(jié)果為1 return 0; }
運行結(jié)果如下:
4.2 在同名全局變量聲明后的全局區(qū)中使用
測試程序如下:(運行成功)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } //同名全局變量 double pail = 2; //在同名全局變量聲明后的全局區(qū)中使用 using namespace Jack; //測試 int main() { using namespace std; //同名局部變量 double pail = 3; //使用 cout << pail << endl; //結(jié)果為3 cout << ::pail << endl; //結(jié)果為2 cout << Jack::pail << endl; //結(jié)果為1 return 0; }
運行結(jié)果如下:
4.3 在同名局部變量聲明前的代碼塊中使用
測試程序如下:(運行成功)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } //同名全局變量 double pail = 2; //測試 int main() { using namespace std; //在同名局部變量聲明前的代碼塊中使用 using namespace Jack; //同名局部變量 double pail = 3; //使用 cout << pail << endl; //結(jié)果為3 cout << ::pail << endl; //結(jié)果為2 cout << Jack::pail << endl; //結(jié)果為1 return 0; }
運行結(jié)果如下:
4.4 在同名局部變量聲明后的代碼塊中使用
測試程序如下:(運行成功)
#include <iostream> //自定義名稱空間 namespace Jack { double pail = 1; } //同名全局變量 double pail = 2; //測試 int main() { using namespace std; //同名局部變量 double pail = 3; //在同名局部變量聲明后的代碼塊中使用 using namespace Jack; //使用 cout << pail << endl; //結(jié)果為3 cout << ::pail << endl; //結(jié)果為2 cout << Jack::pail << endl; //結(jié)果為1 return 0; }
運行結(jié)果如下:
5 總結(jié)
通過上述多個測試,可以得到以下結(jié)論:
- 若僅存在同名全局變量,不存在同名局部變量,使用
using
編譯指令后,在作用域的重合區(qū)域使用變量時一定會引發(fā)名稱沖突。 - 若僅存在同名局部變量,不存在同名全局變量,使用
using
編譯指令將會進(jìn)行名稱解析,不會引發(fā)名稱沖突,但在代碼塊中,同名局部變量將隱藏名稱空間中的變量。 - 若不同名稱空間中存在同名變量,不存在同名全局變量以及同名局部變量,使用
using
編譯指令后,在作用域的重合區(qū)域使用變量時一定會引發(fā)名稱沖突。 - 若名稱空間中的變量、同名全局變量、同名局部局部變量三者同時存在,
using
編譯指令的使用位置不會影響名稱解析的結(jié)果,且不會引發(fā)名稱沖突,這正是using
編譯指令進(jìn)行名稱解析的效果。
以 Jack
名稱空間中的 pail
變量為例,將使用 using
編譯指令時可能遇到的各種情況列表如下,表中的最后一列是指在作用域的重合區(qū)域使用變量時是否會引發(fā)名稱沖突。
到此這篇關(guān)于C++ using 編譯指令與名稱沖突的文章就介紹到這了,更多相關(guān)C++ using 編譯指令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
場景 | 同名全局變量 pail | 同名局部變量pail | 另一名稱空間 Rose 的同名變量 pail | using 編譯指令是否名稱沖突 |
---|---|---|---|---|
1 | 存在 | 無 | 無 | 沖突 |
2 | 存在 | 無 | 存在 | 沖突 |
3 | 無 | 存在 | 無 | 不沖突 |
4 | 無 | 存在 | 存在 | 不沖突 |
5 | 無 | 無 | 存在 | 沖突 |
6 | 存在 | 存在 | 無 | 不沖突 |
7 | 存在 | 存在 | 存在 | 不沖突 |
8 | 無 | 無 | 無 | 不沖突 |
到此這篇關(guān)于C++ using 編譯指令與名稱沖突問題的文章就介紹到這了,更多相關(guān)C++ using 編譯指令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言中字符和字符串處理(ANSI字符和Unicode字符)
這篇文章主要介紹了C語言與C++中字符和字符串處理(ANSI字符和Unicode字符)的詳細(xì)內(nèi)容,非常的全面,這里推薦給大家,希望大家能夠喜歡。2015-03-03Qt編寫地圖之實現(xiàn)經(jīng)緯度坐標(biāo)糾偏
地圖應(yīng)用中都涉及到一個問題就是坐標(biāo)糾偏的問題,這個問題的是因為根據(jù)地方規(guī)則保密性要求不允許地圖廠商使用標(biāo)準(zhǔn)的GPS坐標(biāo),而是要用國家定義的偏移標(biāo)準(zhǔn)。本文將詳細(xì)講解如何在Qt中實現(xiàn)經(jīng)緯度坐標(biāo)糾偏,需要的可以參考一下2022-03-03深入解讀C++ 內(nèi)聯(lián)函數(shù)inline|nullptr
內(nèi)聯(lián)函數(shù):用** inline 修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時C++編譯器會在調(diào)用的地方展開內(nèi)聯(lián)函數(shù)**,這樣調(diào)用內(nèi)聯(lián)函數(shù)就需要創(chuàng)建棧楨,就提高效率了,這篇文章給大家介紹C++ 內(nèi)聯(lián)函數(shù)inline|nullptr的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧2024-07-07