为何要有命名控制
在C语言中并没有命名空间这一个说法,因为C语言中是放在类似于全局命名空间的,遇到有命名冲突时,文件里面可以用static内连接来解决文件之间的命名冲突例如可以在文件a.h中定义static int a;,但是使用全局命名这样的话其他文件想使用这个a命名就无法使用,因此C++为了更好的解决这个命名冲突问题提出了命名空间的技术。
命名控制的使用
首先,我们来说一下C语言中的命名控制,其实C语言中主要是通过static内部链接来控制文件之间命名冲突的,下面我们来说一下static的用法。
1. 第一种用法是在文件中定义全局静态变量,例如在文件test.cpp 中定义全局变量Static int a=5;这样变量a的作用域只存在于该文件中,在其他文件中定义全局变量static int a=5;并不会导致命名冲突,变量a存在数据段的静态区,生存周期是从定义到程序结束。
2. 第二种用法是在函数里面定义局部静态变量,例如
Void fun(){
Static int i=0;
i++;
}
局部变量i的作用域只存在于函数fun中,而且多次调用fun函数只在第一次定义局部变量i,并且把i存在数据段的静态区,其它每次调用都是使用同一个i,也就是说第二次调用fun函数时,变量i的初始值是i=1,而不是i=0;局部静态变量i生存周期从定义到程序结束。
3. 第三种用法是在文件里面定义静态函数,例如Static void fun(){},类似于在文件中定义全局静态变量,该函数的是内连接,作用域只存在于该文件在其他文件中无法使用这些函数。
其次,我们再来说说C++通过使用namespace定义命名空间来解决命名冲突问题。在C++中我们经常会使用using namespace std;来导入std命名空间,这是因为cin/cout等都是存放在这个命名空间里,因此我们可以类似定义命名空间A,如下在文件test.h
#ifndef HHHH
#define HHHH
Namespace A{
ClassB{
Int a;
};
}
#endif
下面我们来说说命名空间定义的一些规则:
a) namespace只能在全局范围内定义,但是它们之间可以相互嵌套,
b) 在namespace 定义的结尾,右括号不需要使用分号,
c) 在一个namespace中定义A命名空间,在另一个文件中可以同样使用这个命名空间,就如同把东西都放在同一个命名空间里。例如在文件testb.h
#ifndef HHHH
#define HHHH
Namespace A{
Class C{
Inta;
};
}
#endif
一个namespace的名字可以用另一个名字来作为别名使用它,例如上例中可以用B使用,如namespace B=A;这样可以解决一些开发者提供的命名过长的问题。
而我们在使用命名空间的可以采用以下几种方式:
a) 第一种使用作用域,例如std::cout<<a;
b) 第二种是使用using指令把所有名字引入到名字空间中,例如using namespace std,同时using指令的用途之一是把名字空间中的所有名字引入到另一个名字空间中,让这些名字嵌套在那个名字空间中,例如
Namespace AA{
Usingnamespace A;
Cobj;
}
c) 第三种是使用using声明一次性引用,这种方法不像using指令那样把那些名字空间当成当前范围的全局名来看待,using神明是在当前范围之内进行的一个声明,这就意味着在这个范围内它可以不顾来自using指令的名字,例如
//test.h
#ifndef TEST_H
#define TEST_H
NamespaceU{
Void f();
Voidg();
}
Namespace V{
Void f();
Void g();
}
#endif
//test.cpp
#include”test.h”
Void h(){
Usingnamespace U;
Using V::f;//using 声明是一个别名,它允许在不同的命名空间声明同样的函数,
f();//calls V::f()
U::f();//必须给出具体的,要不会导致二义性
}