C++的命名空間詳解
C++ | C++命名空間
C++命名空間
一個(gè)中大型軟件往往由多名程序員共同開(kāi)發(fā),會(huì)使用大量的變量和函數(shù),不可避免地會(huì)出現(xiàn)變量或函數(shù)的命名沖突。
當(dāng)所有人的代碼都測(cè)試通過(guò),沒(méi)有問(wèn)題時(shí),將它們結(jié)合到一起就有可能會(huì)出現(xiàn)命名沖突。
例如小李和小韓都參與了一個(gè)文件管理系統(tǒng)的開(kāi)發(fā),它們都定義了一個(gè)全局變量 fp,用來(lái)指明當(dāng)前打開(kāi)的文件,
將他們的代碼整合在一起編譯時(shí),很明顯編譯器會(huì)提示 fp **重復(fù)定義(Redefinition)**錯(cuò)誤。
為了解決合作開(kāi)發(fā)時(shí)的命名沖突問(wèn)題,C++ 引入了**命名空間(Namespace)**的概念。
它可作為附加信息來(lái)區(qū)分不同庫(kù)中相同名稱(chēng)的函數(shù)、類(lèi)、變量等。使用了命名空間即定義了上下文。本質(zhì)上,命名空間就是定義了一個(gè)范圍。
l例如:一個(gè)文件夾(目錄)中可以包含多個(gè)文件夾,每個(gè)文件夾中不能有相同的文件名,但不同文件夾中的文件可以重名。
定義命名空間
命名空間的定義使用關(guān)鍵字 namespace,后跟命名空間的名稱(chēng):
namespace namespace_name { // 代碼:variables/functions/classes }
為了調(diào)用帶有命名空間的函數(shù)或變量,需要在前面加上命名空間的名稱(chēng)。
::
是一個(gè)新符號(hào),稱(chēng)為域解析操作符,在C++中用來(lái)指明要使用的命名空間。
name::code; // code:變量、函數(shù)
實(shí)例1:
/******************************************************************* * > File Name: namespace.cpp * > Create Time: 2021年09月16日 21:32:04 ******************************************************************/ #include <iostream> using namespace std; // 第一個(gè)命名空間 namespace space1{ void func(){ cout << "Inside first space" << endl; } } // 第二個(gè)命名空間 namespace space2{ void func(){ cout << "Inside second space" << endl; } } int main(int argc, char* argv[]) { space1::func(); // 調(diào)用第一個(gè)空間的函數(shù) space2::func(); // 調(diào)用第二個(gè)空間的函數(shù) return 0; }
編譯、運(yùn)行:
PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> make g++ -o namespace namespace.cpp -g -Wall PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> .\namespace.exe Inside first space Inside second space
using 指令
您可以使用 using namespace 指令,這樣在使用命名空間時(shí)就可以不用在前面加上命名空間的名稱(chēng)。
這個(gè)指令會(huì)告訴編譯器,后續(xù)的代碼將使用指定的命名空間中的名稱(chēng)。
實(shí)例2:
/******************************************************************* * > File Name: using-namespace.cpp * > Create Time: 2021年09月16日 21:43:39 ******************************************************************/ #include <iostream> using namespace std; namespace space1{ void func(void){ cout << "inside first namespace" << endl; } }// namespace space1 namespace space2{ void func(void){ cout << "inside second namespace" << endl; } } // namespace space2 using namespace space2; int main(int argc, char* argv[]) { func(); // 調(diào)用第一個(gè)命名空間中的函數(shù) return 0; }
編譯、運(yùn)行:
PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> make g++ -o using-namespace using-namespace.cpp -g -Wall PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> .\using-namespace.exe inside second namespace
using 指令也可以用來(lái)指定命名空間中的特定項(xiàng)目。
例如,如果您只打算使用 std 命名空間中的 cout 部分,您可以使用如下的語(yǔ)句:
using std::cout;
隨后的代碼中,在使用 cout 時(shí)就可以不用加上命名空間名稱(chēng)作為前綴,但是 std 命名空間中的其他項(xiàng)目仍然需要加上命名空間名稱(chēng)作為前綴。
實(shí)例3:
/******************************************************************* * > File Name: using-namespace1.cpp * > Create Time: 2021年09月16日 21:57:40 ******************************************************************/ #include <iostream> using std::cout; int main(int argc, char* argv[]) { cout << "std::endl is used with std!" << std::endl; return 0; }
編譯、運(yùn)行:
PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> make g++ -o using-namespace1 using-namespace1.cpp -g -Wall PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> .\using-namespace1.exe std::endl is used with std!
using 指令引入的名稱(chēng)遵循正常的范圍規(guī)則。名稱(chēng)從使用 using 指令開(kāi)始是可見(jiàn)的,直到該范圍結(jié)束。此時(shí),在范圍以外定義的同名實(shí)體是隱藏的。
不連續(xù)的命名空間
命名空間可以定義在幾個(gè)不同的部分中,因此命名空間是由幾個(gè)單獨(dú)定義的部分組成的。
一個(gè)命名空間的各個(gè)組成部分可以分散在多個(gè)文件中。
所以,如果命名空間中的某個(gè)組成部分需要請(qǐng)求定義在另一個(gè)文件中的名稱(chēng),則仍然需要聲明該名稱(chēng)。
下面的命名空間定義可以是定義一個(gè)新的命名空間,也可以是為已有的命名空間增加新的元素:
namespace namespace_name { // 代碼聲明 }
嵌套的命名空間
命名空間可以嵌套,您可以在一個(gè)命名空間中定義另一個(gè)命名空間,如下所示:
namespace namespace_name1 { // 代碼聲明 namespace namespace_name2 { // 代碼聲明 } }
您可以通過(guò)使用 :: 運(yùn)算符來(lái)訪問(wèn)嵌套的命名空間中的成員:
// 訪問(wèn) namespace_name2 中的成員 using namespace namespace_name1::namespace_name2; // 訪問(wèn) namespace:name1 中的成員 using namespace namespace_name1;
實(shí)例4:
/******************************************************************* * > File Name: namespace-namespace.cpp * > Create Time: 2021年09月16日 22:18:52 ******************************************************************/ #include <iostream> using namespace std; // 第一個(gè)命名空間 namespace first_space{ void func(){ cout << "Inside first_space" << endl; } // 第二個(gè)命名空間 namespace second_space{ void func(){ cout << "Inside second_space" << endl; } } } using namespace first_space::second_space; int main () { // 調(diào)用第二個(gè)命名空間中的函數(shù) func(); return 0; }
編譯、運(yùn)行:
PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> make g++ -o namespace-namespace namespace-namespace.cpp -g -Wall PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> .\namespace-namespace.exe Inside second_space
實(shí)例5:
關(guān)于命名空間內(nèi)變量和函數(shù)及全局變量的使用和作用域:
/******************************************************************* * > File Name: namespace1.cpp * > Create Time: 2021年09月16日 22:24:18 ******************************************************************/ #include <iostream> using namespace std; namespace A { int a = 100; namespace B //嵌套一個(gè)命名空間B { int a =20; } } int a = 200;//定義一個(gè)全局變量 int main(int argc, char *argv[]) { cout <<"A::a ="<< A::a << endl; cout <<"A::B::a ="<<A::B::a << endl; cout <<"a ="<<a << endl; cout <<"::a ="<<::a << endl; int a = 30; cout <<"a ="<<a << endl; cout <<"::a ="<<::a << endl; return 0; }
編譯、運(yùn)行:
PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> make g++ -o namespace1 namespace1.cpp -g -Wall PS D:\2.SoftTools\cygwin64\home\fly\workSpace\cplusplus\day3> .\namespace1.exe A::a =100 A::B::a =20 a =200 //全局變量a ::a =200 a =30 //局部變量a ::a =200
即:全局變量 a 表達(dá)為 ::a,用于當(dāng)有同名的局部變量時(shí)來(lái)區(qū)別兩者。
筆記:
實(shí)例6:
/******************************************************************* * > File Name: namespace2.cpp * > Author: fly * > Mail: 1358326274@qq.com * > Create Time: 2021年09月16日 22:28:21 ******************************************************************/ #include <iostream> using namespace std; namespace A { int a = 100; int fun() { cout<<"a = "<<a<<endl; } namespace B //嵌套一個(gè)命名空間B { int a =20; int fun() { cout<<"a = "<<a<<endl; } } } int main(int argc, char *argv[]) { cout<<a<<endl;// 錯(cuò)誤:‘a(chǎn)'在此作用域中尚未聲明 fun();// 錯(cuò)誤:‘fun'在此作用域中尚未聲明 return 0; }
解決辦法: 用 using 來(lái)告訴編譯器用到的是哪個(gè)命名空間內(nèi)的內(nèi)容。
在 main() 上面加 using namespace A; 或者 using namespace A::B; 。
這樣就可以使用其中的 a 和 fun()。
但是不能同時(shí)使用,因?yàn)檫@樣也會(huì)導(dǎo)致編譯出錯(cuò),編譯器器不知道要去使用哪個(gè) a 和 fun()。
實(shí)例7:
命名空間沖突
/******************************************************************* * > File Name: namespace3.cpp * > Create Time: 2021年09月16日 22:32:58 ******************************************************************/ #include <iostream> using namespace std; namespace A { int a = 100; namespace B //嵌套一個(gè)命名空間B { int a = 20; } } int a = 200;//定義一個(gè)全局變量 int main(int argc, char *argv[]) { cout << "A::a =" << A::a << endl; //A::a =100 cout << "A::B::a =" << A::B::a << endl; //A::B::a =20 cout << "a =" << a << endl; //a =200 cout << "::a =" << ::a << endl; //::a =200 using namespace A; /* 錯(cuò)誤:對(duì)‘a(chǎn)'的引用有歧義 */ cout << "a =" << a << endl; // Reference to 'a' is ambiguous // 命名空間沖突,編譯期錯(cuò)誤 cout << "::a =" << ::a << endl; //::a =200 int a = 30; cout << "a =" << a << endl; //a =30 cout << "::a =" << ::a << endl; //::a =200 //即:全局變量 a 表達(dá)為 ::a,用于當(dāng)有同名的局部變量時(shí)來(lái)區(qū)別兩者。 using namespace A; cout << "a =" << a << endl; // a =30 // 當(dāng)有本地同名變量后,優(yōu)先使用本地,沖突解除 cout << "::a =" << ::a << endl; //::a =200 return 0; }
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C指針原理教程之語(yǔ)法樹(shù)及其實(shí)現(xiàn)
本文給大家分享的是如何使用C語(yǔ)言的指針原來(lái)來(lái)實(shí)現(xiàn)語(yǔ)法樹(shù),并給大家提供了詳細(xì)的實(shí)例代碼,希望大家能夠喜歡2019-02-02詳解_beginthreadex()創(chuàng)建線程
這篇文章主要介紹了詳解_beginthreadex()創(chuàng)建線程,使用_beginthreadex(),需要的頭文件支持#include <process.h> 下面我們就來(lái)看看具體的實(shí)現(xiàn)吧2022-01-01C/C++中二進(jìn)制文件&順序讀寫(xiě)詳解及其作用介紹
這篇文章主要介紹了C/C++中二進(jìn)制文件&順序讀寫(xiě)詳解及其作用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09C++面試題之進(jìn)制轉(zhuǎn)換的實(shí)例
這篇文章主要介紹了C++面試題之進(jìn)制轉(zhuǎn)換的實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這樣的知識(shí),需要的朋友可以參考下2017-10-10linux c 獲得當(dāng)前進(jìn)程的進(jìn)程名和執(zhí)行路徑(示例)
如何得到當(dāng)前進(jìn)程的進(jìn)程名和執(zhí)行路徑。寫(xiě)了個(gè)程序分享一下2013-07-07C語(yǔ)言詳細(xì)講解if語(yǔ)句與switch語(yǔ)句的用法
用 if 語(yǔ)句可以構(gòu)成分支結(jié)構(gòu),它根據(jù)給的條件進(jìn)行判定,以決定執(zhí)行哪個(gè)分支程序段,C 語(yǔ)言中還有另外一種分支語(yǔ)句,就是 switch 語(yǔ)句2022-05-05