命名空間
命名空間一般是對全局變量,函數(shù),類做處理的,以防多個重名變量引起的重定義錯誤。命名空間主要分為三種
- 你指定的命名空間
namespace A{
char c;
int i;
double d;
}
你指定了一個名字為A的命名空間。這種命名空間具有外部鏈接屬性,也就是說這個空間里的變量和函數(shù)會和其他文件同一名字的命名空間一起鏈接。
在同一個項目里,test1.cpp的內(nèi)容為
namespace A {
int a;//默認是外部屬性external
}
把main.cpp內(nèi)容為
#include"test1.cpp"
int main(){
}
編譯鏈接的時候就會報錯
CMakeFiles/joinordetach.dir/test1.cpp.o:test1.cpp:(.bss+0x0): multiple definition of `A::a'
CMakeFiles/joinordetach.dir/main.cpp.o:main.cpp:(.bss+0x0): first defined here
重定義錯誤,因為在同一個命名空間里有多個同名變量分配了不同空間地址,a在test1.cpp里分配了空間,也在main.cpp里分配了空間。鏈接器不知道哪個空間才是該變量的正確地址。
所以不能在多個文件的同一個命名空間里定義同名變量,只能在其中一個文件定義,而別的文件里聲明引用,對這兩個文件進行如下修改
test1.cpp內(nèi)容改成
#include <iostream>
namespace A {//定義了一個命名空間
extern int a;//聲明了a,默認是外部屬性external
void fun();/聲明了fun(),/默認是外部屬性external
}
main.cpp內(nèi)容改成
#include<iostream>
#include "test1.cpp"
int A::a=3;//定義a
void A::fun()//定義函數(shù)fun
{
std::cout << "hello world" << std::endl;
}
int main() {
std::cout << A::a << std::endl;//使用命名空間A里的a
A::fun();//使用命名空間A里的fun
}
結(jié)果是
3
hello world
使用另外一個cpp里命名空間里的變量的方法
test1.cpp里內(nèi)容如下
namespace A{
int a=5;
}
main.cpp里內(nèi)容如下
#include <iostream>
namespace A{
extern int a;
}
int main()
{
std::cout<<A::a<<std::endl;
}
輸出結(jié)果為
5
- 如果你不加指定,則默認使用全局命名空間,在同一個項目里,多個文件要是都沒指定命名空間,則這一個項目使用默認的全局命名空間,全局命名空間里的變量和函數(shù)都是外部鏈接屬性,即可以被另一個文件引用,注意這里的變量和函數(shù)都是全局的,而非局部作用域里的變量(比如main函數(shù)里的變量)。
在同一個項目里有兩個文件,一個"test.cpp"
#include <iostream>
int a=10;//默認是外部屬性external
void fun()//默認是外部屬性external
{
std::cout<<"hello world"<<std::endl;
}
另一個"main.cpp"
# include<iostream>
using namespace std;
extern int a;//聲明a在別的地方定義了
extern void fun();//聲明函數(shù)fun在別的地方定義了
int main()
{
cout<<a<<endl;//使用a
fun();
}
運行結(jié)果如下
10
hello world
- 匿名空間
# include<iostream>
namespace {
char c;
int i=3;
double d;
}
int main()
{
std::cout<<i<<std::endl;
}
輸出結(jié)果
3
你可以省略命名空間的名字,則該空間的所有變量只能被當前文件所引用,而不能被同一個項目里別的文件使用。這些變量具有internal鏈接屬性,這和聲明為static的全局名稱的鏈接屬性是相同的,即名稱的作用域被限制在當前文件中,無法通過在另外的文件中使用extern聲明來進行鏈接。命名空間都是具有external 連接屬性的,只是匿名的命名空間產(chǎn)生的UNIQUE_NAME在別的文件中無法得到,這個唯一的名字是不可見的。