命名空间
定义命名空间
定义格式: 定义命名空间需要使用namespace关键字
namespace 名称 { 常量,变量,函数等对象的定义 }
代码语言:javascript复制 namespace name1
{
int names = 12;
int age = 32;
}
此代码的意思也就是说,names ,age两个变量是属于命名空间name1的。 那么我们怎么去使用这两个变量呢? 一般使用形式如下:
代码语言:javascript复制命名空间::成员; 比如:
name1::age = 20;
那么唯一性是如何体现的呢。下面的例子来说明命名空间包含的变量成员具有唯一性
代码语言:javascript复制 1 #include<iostream>
2 using namespace std;
3 namespace name1
4 {
5 int names = 12;
6 int age = 32;
7 }
8 namespace name2
9 {
10 int names = 20;
11 int age = 325;
12 }
13 int age = 6;
14 int main()
15 {
16 cout<<"name1 :names = "<<name1::names<<" : age = "<<name1::age<<endl;
17 cout<<"name2 :names = "<<name2::names<<" : age = "<<name2::age<<endl;
18 cout<<" age = "<<age<<endl;
19 return 0;
20 }
结果:
代码语言:javascript复制[bsk@localhost c ]$ g namespace.cpp
[bsk@localhost c ]$ ./a.out
name1 :names = 12 : age = 32
name2 :names = 20 : age = 325
age = 6
可见不同命名空间下的同名称变量是不一样的。而且全局变量和命名空间的变量也不会一样。
使用命名空间
在同一个应用程序的多个文件中,有时候会存在同名的全局对象,这样会导致应用程序的链接错误。命名空间是一个命名的范围区域,程序员在这个特定的范围内创建的所有标识符都是唯一的。 使用命名空间是消除命名冲突的最佳方式!
代码语言:javascript复制 1 #include<iostream>
2 using namespace std;
3 namespace name1
4 {
5 int names = 12;
6 int age = 32;
7 }
8 namespace name2
9 {
10 int names = 12;
11 int age = 325;
12 }
13
14 int main()
15 {
16
17 return 0;
18 }
~
就像上面的代码所示,两个int 变量 names,age虽然名称相同,但是他们来源于不相同命名空间,所以并不冲突,从而保证了标识符的唯一性。
通过使用命名空间,可以定义相同名称的变量表示不同的值,而且可以正确进行引用显示。其实还有一种引用命名空间中的成员方法。就是用using namespace 语句 一般格式:
using namespace 命名空间名称
比如我们常用的 using namespace std; 使用using namespace 语句,则可以引用空间中的成员时直接使用。
代码语言:javascript复制 1 #include<iostream>
2 using namespace std;
3 namespace name1
4 {
5 int names = 12;
6 int age = 32;
7 }
8 using namespace name1;
9 namespace name2
10 {
11 int names = 20;
12 int age = 325;
13 }
14 int main()
15 {
16 cout<<" name1 : names= "<<names<<" age = "<<age<<endl;
17 cout<<"name2 :names = "<<name2::names<<" : age = "<<name2::age<<endl;
18 return 0;
19 }
~
代码语言:javascript复制[bsk@localhost c ]$ ./a.out
name1 : names= 12 age = 32
name2 :names = 20 : age = 325
运行结果·和·上面的一样。但是还有一个缺点,就是当我们使用using namespace语句使用命名空间时,当我们定义多个命名空间,正好里面有相同的标识符成员(变量名称相同),那么就会产生歧义。所以这个时候最好就使用作用域限定符来进行引用。 如下面错误所示:
代码语言:javascript复制namespace.cpp: In function ‘int main()’:
namespace.cpp:17:31: error: reference to ‘names’ is ambiguous
cout<<" name1 : names= "<<names<<" age = "<<age<<endl;
^
namespace.cpp:11:9: note: candidates are: int name2::names
int names = 20;
^
namespace.cpp:5:9: note: int name1::names
int names = 12;
^
namespace.cpp:17:49: error: reference to ‘age’ is ambiguous
cout<<" name1 : names= "<<names<<" age = "<<age<<endl;
^
namespace.cpp:12:9: note: candidates are: int name2::age
int age = 325;
^
namespace.cpp:6:9: note: int name1::age
int age = 32;
^
namespace.cpp:18:29: error: reference to ‘names’ is ambiguous
cout<<" name2:: names="<<names<<endl;
^
namespace.cpp:11:9: note: candidates are: int name2::names
int names = 20;
^
namespace.cpp:5:9: note: int name1::names
int names = 12;
在多文件中定义命名空间
在定义命名空间时,通常在头文件中声明命名空间中的函数,在源文件中定义命名空间中的函数,将程序的声明与实现分开。
头文件:
代码语言:javascript复制namespace output
{
void test(); //声明函数
}
源文件:
代码语言:javascript复制void output::test()
{
cout<<"this is test"<<endl;
}
定义嵌套的命名空间
代码语言:javascript复制namespace output
{
void show()
{
cout<<"output function"<<endl;
}
namespace myname
{
void demo()
{
cout<<"my name function"<<endl;
}
}
}
在上述代码中,在output命名空间中又定义了一个命名空间myname,如果程序访问myname命名空间对象,可以使用外层和内层的命名空间作为前缀。
output::myname::demo();
那么你觉得using namespace output::myname; 语句是使用哪个命名空间呢?其实上面这个语句仅仅只是引用了嵌套在output中的myname命名空间,并没有引用output命名空间,所以output命名空间下的show函数也就无法调用。
未命名空间
代码语言:javascript复制namespace
{
int age = 10;
}
在无名命名空间中定义的标识符被设置为全局命名空间,这样也就违背了命名空间的设置原则,所以未命名空间就没有得到普及。