C++ | C++命名空間
C++命名空間
一個中大型軟件往往由多名程序員共同開發,會使用大量的變量和函數,不可避免地會出現變量或函數的命名沖突。
當所有人的代碼都測試通過,沒有問題時,將它們結合到一起就有可能會出現命名沖突。
例如小李和小韓都參與了一個文件管理系統的開發,它們都定義了一個全局變量 fp,用來指明當前打開的文件,
將他們的代碼整合在一起編譯時,很明顯編譯器會提示 fp **重復定義(Redefinition)**錯誤。
為了解決合作開發時的命名沖突問題,C++ 引入了**命名空間(Namespace)**的概念。
它可作為附加信息來區分不同庫中相同名稱的函數、類、變量等。使用了命名空間即定義了上下文。本質上,命名空間就是定義了一個范圍。
l例如:一個文件夾(目錄)中可以包含多個文件夾,每個文件夾中不能有相同的文件名,但不同文件夾中的文件可以重名。
定義命名空間
命名空間的定義使用關鍵字 namespace,后跟命名空間的名稱:
1
2
3
4
|
namespace namespace_name { // 代碼:variables/functions/classes } |
為了調用帶有命名空間的函數或變量,需要在前面加上命名空間的名稱。
::
是一個新符號,稱為域解析操作符,在C++中用來指明要使用的命名空間。
1
|
name::code; // code:變量、函數 |
實例1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/******************************************************************* * > File Name: namespace.cpp * > Create Time: 2021年09月16日 21:32:04 ******************************************************************/ #include <iostream> using namespace std; // 第一個命名空間 namespace space1{ void func(){ cout << "Inside first space" << endl; } } // 第二個命名空間 namespace space2{ void func(){ cout << "Inside second space" << endl; } } int main( int argc, char * argv[]) { space1::func(); // 調用第一個空間的函數 space2::func(); // 調用第二個空間的函數 return 0; } |
編譯、運行:
1
2
3
4
5
|
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 指令,這樣在使用命名空間時就可以不用在前面加上命名空間的名稱。
這個指令會告訴編譯器,后續的代碼將使用指定的命名空間中的名稱。
實例2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/******************************************************************* * > 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(); // 調用第一個命名空間中的函數 return 0; } |
編譯、運行:
1
2
3
4
|
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 指令也可以用來指定命名空間中的特定項目。
例如,如果您只打算使用 std 命名空間中的 cout 部分,您可以使用如下的語句:
1
|
using std::cout; |
隨后的代碼中,在使用 cout 時就可以不用加上命名空間名稱作為前綴,但是 std 命名空間中的其他項目仍然需要加上命名空間名稱作為前綴。
實例3:
1
2
3
4
5
6
7
8
9
10
11
|
/******************************************************************* * > 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; } |
編譯、運行:
1
2
3
4
|
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 指令引入的名稱遵循正常的范圍規則。名稱從使用 using 指令開始是可見的,直到該范圍結束。此時,在范圍以外定義的同名實體是隱藏的。
不連續的命名空間
命名空間可以定義在幾個不同的部分中,因此命名空間是由幾個單獨定義的部分組成的。
一個命名空間的各個組成部分可以分散在多個文件中。
所以,如果命名空間中的某個組成部分需要請求定義在另一個文件中的名稱,則仍然需要聲明該名稱。
下面的命名空間定義可以是定義一個新的命名空間,也可以是為已有的命名空間增加新的元素:
1
|
namespace namespace_name { // 代碼聲明 } |
嵌套的命名空間
命名空間可以嵌套,您可以在一個命名空間中定義另一個命名空間,如下所示:
1
2
3
4
5
6
|
namespace namespace_name1 { // 代碼聲明 namespace namespace_name2 { // 代碼聲明 } } |
您可以通過使用 :: 運算符來訪問嵌套的命名空間中的成員:
1
2
3
4
|
// 訪問 namespace_name2 中的成員 using namespace namespace_name1::namespace_name2; // 訪問 namespace:name1 中的成員 using namespace namespace_name1; |
實例4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/******************************************************************* * > File Name: namespace-namespace.cpp * > Create Time: 2021年09月16日 22:18:52 ******************************************************************/ #include <iostream> using namespace std; // 第一個命名空間 namespace first_space{ void func(){ cout << "Inside first_space" << endl; } // 第二個命名空間 namespace second_space{ void func(){ cout << "Inside second_space" << endl; } } } using namespace first_space::second_space; int main () { // 調用第二個命名空間中的函數 func(); return 0; } |
編譯、運行:
1
2
3
4
|
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 |
實例5:
關于命名空間內變量和函數及全局變量的使用和作用域:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/******************************************************************* * > File Name: namespace1.cpp * > Create Time: 2021年09月16日 22:24:18 ******************************************************************/ #include <iostream> using namespace std; namespace A { int a = 100; namespace B //嵌套一個命名空間B { int a =20; } } int a = 200; //定義一個全局變量 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; } |
編譯、運行:
1
2
3
4
5
6
7
8
9
|
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 表達為 ::a,用于當有同名的局部變量時來區別兩者。
筆記:
實例6:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
/******************************************************************* * > File Name: namespace2.cpp * > Author: fly * > Mail: [email protected] * > 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 //嵌套一個命名空間B { int a =20; int fun() { cout<< "a = " <<a<<endl; } } } int main( int argc, char *argv[]) { cout<<a<<endl; // 錯誤:‘a'在此作用域中尚未聲明 fun(); // 錯誤:‘fun'在此作用域中尚未聲明 return 0; } |
解決辦法: 用 using 來告訴編譯器用到的是哪個命名空間內的內容。
在 main() 上面加 using namespace A; 或者 using namespace A::B; 。
這樣就可以使用其中的 a 和 fun()。
但是不能同時使用,因為這樣也會導致編譯出錯,編譯器器不知道要去使用哪個 a 和 fun()。
實例7:
命名空間沖突
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/******************************************************************* * > File Name: namespace3.cpp * > Create Time: 2021年09月16日 22:32:58 ******************************************************************/ #include <iostream> using namespace std; namespace A { int a = 100; namespace B //嵌套一個命名空間B { int a = 20; } } int a = 200; //定義一個全局變量 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; /* 錯誤:對‘a'的引用有歧義 */ cout << "a =" << a << endl; // Reference to 'a' is ambiguous // 命名空間沖突,編譯期錯誤 cout << "::a =" << ::a << endl; //::a =200 int a = 30; cout << "a =" << a << endl; //a =30 cout << "::a =" << ::a << endl; //::a =200 //即:全局變量 a 表達為 ::a,用于當有同名的局部變量時來區別兩者。 using namespace A; cout << "a =" << a << endl; // a =30 // 當有本地同名變量后,優先使用本地,沖突解除 cout << "::a =" << ::a << endl; //::a =200 return 0; } |
總結
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!
原文鏈接:https://blog.csdn.net/I_feige/article/details/120335534