c++ 命名空间(这一篇就够了)

1.为什么需要命名空间?

 using namespace std;

这句话我们几乎每次在c++程序中看见,这就是使用了命名空间std.

命名空间是ANSI C++引入的可以由用户命名的作用域,用来处理程序中常见的命名冲突。
在C语言中定义了3个层次的作用城:文件(编译单位)函数复合语句,C++又引人了类作用域,类是出现在文件内的。在不同的作用域中可以定义相同名字的变量。互不干扰,便于系统区别它们。
有关作用域的例子:
如果在文件中定义了两个类,在这两个类中可以有同名的函数,在引用时,为了区别,应该加上类名作为限定,如:

class A //声明A类
{	
public:
	void funl ();//声明A类中的funl函数
private:
	int i;
);
vold A::funl ()//定义A类中的fun1函数

{
	//
}


class B //声明B类
{public:
	void funl () ;//B类中也有funl函数
	void fun2 () ;
};
void B: :funl ()//定义B类中的funl函数
{
	//
}

这样就不会混淆。

在文件中可以定义全局变量,它的作用域是整个程序。但是如果在文件A中定义了一个全局变量a:

int  a=1;

在文件B中定义了也一个全局变量a:

int a=2;

在对文件A和B单独编译时不会有问题,但是一个程序中包含这两个文件,在链接时就会报错,因为在同一个程序里有两个同名的变量,认为是对变量的重复定义。问题就在于全局变量的作用域在整个程序,在同一作用域中不该有两个或做多上同名的实体,包括变量,函数和类等。
虽然可以通过extern 声明同一程序中的同名变量是同一个变量。如果在文件B中有以下声明:

extern int a;

表示文件B中的变量a是在外部其他文件中已定义的变量,由此声明,编译时文件A的变量a的作用域就扩展到了文件B,运行时就不会有报错了,但是在一个有若干个人完成的大型程序中,不同的人分别定义了类,放在不同的头文件中,在主文件中需要这些类时,就有可能出现在不同的头文件中使用了相同的名字来命名类和函数,这样就会在程序中出现命名冲突。
显然这就需要提出方法来解决这个问题,所以才有了命名空间这个概念。

2.什么是命名空间

所谓命名空间,实际上就是一个程序设计者命名的内存空间,设计者可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。
如:

namespace ns1  //指定命名空间ns1
{
	int a;
	int fun1();
}

说明:namespace是定义命名空间必须写的关键字,ns1是用户自己定义的指定命名空间的名字,花括号里是声明块,声明的实体成为命名空间成员,a,fun1,任然是全局变量,只是隐藏在命名空间中。若要在程序中使用他们,必须要加上命名空间名和作用域分辨符“::”,如ns1::a,这被称为命名空间限定。C++中命名空间的作用类似于操作系统中的目录和文件的关系,由于文件很多,不便管理,而且容易重名,于是人们设立若干子目录,把文件分别放到不同的子目录中,不同子目录中的文件可以同名。调用文件时应指出文件路径。
命名空间的作用是建立一些互相分隔的作用域,把一些全局实体分隔开来,以免产生名字冲突。例如某中学高三年级有3个叫刘飞的学生,如果都在同班,那么老师点名叫刘飞时,3个人都站起来应答,这就是名字冲突,同名者无法互相区分。为了避免同名混滑,把他们分到三个组,根据组号来叫人,一组刘飞,二组刘飞,这样就不会产生混淆了。

3.命名空间的使用

一般的使用规则:命名空间名::命名空间成员名

果然是因为“懒”,科技才在一直进步,又是命名空间的名字比较长,再来个嵌套,就会感觉不太方便,为此,c++提供了一些机制,可以简化命名空间的使用手续。
3.1使用命名空间别名
为命名空间起一个别名,如:

namespace  TTTTTTTTT
{
//
}
//起一个短名字替代它
namespace T=TTTTTTTTT;     //别名T与TTTTTTTTT等价

3.2使用 using 命名空间单个成员名
using后面必须加命名空间成员名必须是有命名空间限定的名字。如:

using ns1::Students;

以上语句声明:在本作用域中(using所在的作用域)中会用到命名空间ns1中的成员a,之后在本作用域中使用a时,就不必每次都加上命名空间限定。
例如:有了上面的声明后:

Students std1(110,"liufei",22);//此处的Students相当于 ns1::Students

不加声明就是这样:

ns1::Students std1(110,"liufei",22);

3.3使用”using namespace 命名空间名“
若是一个命名空间里有多个命名空间成员实体,就需要多次使用 “using 命名空间单个成员名”,但是可以使用using namespace 命名空间名 语句来声明一个命名空间的全部成员。如:

using namespace ns1;

这样使用后,命名空间ns1里的成员就好像是在全局域声明一样,就不用再使用时用命名空间限定了。
3.4无名的命名空间
文件A中声明了以下无名命名空间:

namespace
{
	void fun()
	{
		cout <<"hello"<<endl;
	}
}

由于没有名字,在其他文件中显然无法引用,他只在本文件A中有效,作用域就是文件A里,
可以联想到C语言中的static声明的函数,其作用也是使该函数的作用域限于本文件。

3.5标准命名空间std(standard)
标准c++库里的所有标识符都是在一个名为std的命名空间里定义的,或者说标准头文件(如iosteram)中函数,类,对象和类模板都是在命名空间std中定义的。
这样,在程序中要使用c++标准库时,就需要使用std作为限定,就有了开篇我们所谈到的这句声明:
using namespace std;
这样,在std中定义和声明的所有标识符在本文件中都可以作为全局变量来用。

3.6使用早期的C语言库
在c++中使用头文件的两种方法
1.用在C语言中的传统方法
头文件名加后缀.h,如stdio.h,math.h等,
2.用c++的新方法
c++标准头文件不再包含后缀.h,例如iostream,string都是c++的头文件名,为了表示c与c++的联系与区别,c++所用的c头文件不加后缀且前面加一个字母c,如c中的stdio.h,在c++中相应的头文件就是cstdio。

发布了29 篇原创文章 · 获赞 8 · 访问量 1993

猜你喜欢

转载自blog.csdn.net/qq_44785014/article/details/104271974
今日推荐