笔者正在学习C++语言,啃书系列将会持续更新,希望可以同大家一起学习,一起进步。如果文章有帮助的话,记得点赞、收藏、关注一条龙哦。
系列文章:
啃书《C++ Primer Plus》之 C++ 函数指针
啃书《C++ Primer Plus》之 C++ 名称空间1
本文是名称空间的第二部分,第一部分见《名称空间1》
名称空间的嵌套与别名
一开始提到,名称空间可以存在于另一个名称空间中,形成嵌套的结构。不仅如此,在名称空间中,还可以使用using声明和using编译指令引用其他名称空间的名称。
访问一个名称空间中的名称空间的方式是作用域解析符,写作:
外层名称空间::内层名称空间
当然,如果有多层嵌套,则可以继续使用作用域解析符。
综上,我们来举个例子:
#include <iostream>
namespace A
{
int a = 10;
}
namespace B
{
int b = 20;
}
namespace C
{
using namespace A;
using B::b;
int c = a * 2 + b;
namespace D
{
int d = 50;
}
}
int main()
{
using namespace std;
cout << "A::a is : " << A::a << endl;
cout << "B::b is : " << B::b << endl;
cout << "C::c is : " << C::c << endl;
cout << "C::D::d is :" << C::D::d << endl;
return 0;
}
运行结果为:
另外,我们还可以像为变量赋值一般为名称空间起别名,语法如下:
namespace 新的名称 = 某名称空间;
这样一来,便可以简化对名称的访问。例如为上面代码中的D起别名:
...
namespace newD = C::D;
cout << "newD::d is :" << newD::d << endl;
...
需要说明的是,为名称空间取别名的语句是可以在代码块中使用的!
未命名名称空间的使用
有一类名称空间,他们没有名字,长这个亚子:
namespace
{
...
}
这样的,没有名字的名称空间,被称为未命名名称空间,该名称空间中声明的名称的作用于为:从声明点到该声明区域末尾。 加之名称空间只能位于代码块之外定义。这为内部静态变量提供了代替品。
例如,有如下代码:
...
namespace
{
int a = 10;
int b = 2;
}
...
其中对a和b的定义,相当于:
...
static int a = 10;
static int b = 2;
...
作用域是整个文件,连接性是内部的,其他文件不可访问.
需要注意的是,在这个名称空间之前的代码不可以使用其中的名称。
名称空间的使用规范
上文,我们介绍了名称空间的各种用法和特性。下面,根据书中作者的指导原则,尝试着总结几条使用名称空间的规范。
使用名称空间代替全局变量和静态变量
名称空间出现的目的之一就是为了解决全局变量或是函数的名称冲突问题。所以,在编写工程文件时,尽可能将提供给外界使用的名称定义在名称空间中。另外,未命名名称空间可作为代替静态全局变量的作用。
尽可能少用using编译指令
在探讨名称空间造成的冲突时,我们讨论过using编译指令。它会引入名称空间中全部的名称,并会代替局部变量名称造成错误。
另外,由于它的覆盖作用,不要在全局尤其是头文件中使用using编译指令。
将编译指令用于转换旧代码
在C语言的许多类库中,没有名称空间的机制,而在c++版本的类库中,这些类库引入了名称空间这个属性并将名称放入了 std中,因此,可以将using编译指令作为将旧代码翻新的权宜之计。
最后,对于更一般的名称的使用,using声明应该首选放在局部而非全局。更加首选的则是通过作用域解析符来访问这个名称。