【C++】从入门到精通第四弹——命名空间

2023-11-09 10:33:43 浏览数 (1)

命名空间

定义命名空间

定义格式: 定义命名空间需要使用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;
}

在无名命名空间中定义的标识符被设置为全局命名空间,这样也就违背了命名空间的设置原则,所以未命名空间就没有得到普及。

0 人点赞