C++你所不知道的命名空间
我们每天都在用using namespace std;
但你对命名空间了解多少?
这是个啥?
命名空间是一种机制,用来把单个标识符下存在大量有逻辑联系的程序实体组合到一起,并以此标识符作为此组群的名字。
换一种说法,就是一个集合,其关键字就是命名空间的名字
using namespace name
{
/* code */
} ;// namespace name
相关的几个概念(这三个作用域逐次减小)
- 声明域(declaration region):声明标识符的区域
- 潜在作用域(potential scope):从声明点开始,到声明域末尾的区域。(因为C++是先声明后使用的原则,所以声明点之前的声明域中,标识符是不能用的)
- 作用域(scope):即标识符对程序可见的范围,即真正在使用的范围
CAUTION:MS的MFC(微软基础类库)中没有使用命名空间,但.NET有很多使用
定义命名空间
命名空间可以定义有名的和无名的(就像你定义一个struct结构体一样)
结合一个小例子:
namespace Outer
{
int i; // 命名空间Outer的成员i的内部定义
namespace Inner // 子命名空间Inner的内部定义
{
void Fun1() { i++; } // i为 Outer::i
int i;
void Fun2() { i++; } // Inner::i
void Fun3();
} // namespace Inner
void Fun1();
// namespace Inner2; // 错误,不能 声明 (而非定义)子命名空间
} // namespace Outer
void Outer::Fun1()
{
i--;
}
void Outer::Inner::Fun3()
{
i--;
}
- 不能在命名空间的定义中声明(另一个嵌套的)子命名空间,只能定义子命名空间
- 命名空间必须定义在头文件中,所以记得新建一个 .h 文件哦
- 命名空间是开放的,这也就意味着可以随时将新的成员名称加入到已有的命名空间中去,但规则嘛,就是不能直接使用
命名空间名::成员名
的形式,而必须先在命名空间的定义中声明,方法是多次声明和定义同一命名空间,每次添加新成员 还可以组合现有的命名空间(使用using)
For example:namespace sample
{int i;
void Fun1();
} // 现在有成员i, Fun1()
namespace sample // 重新定义命名空间sample
{int j;
void Fun2()
} // 现在有成员i, Fun1(), j, Fun2()
namespace sample1
{using namespace sample;
void Fun3();
} // 组合命名空间
使用它!
- 使用作用域运算符“: :“ (就像你对类成员所做的那样)
使用using指令
- 标准C++库(不包括标准C库)中所包含的所有内容(包括常量,变量,结构,类和函数, etc.)都被定义在命名空间std(standard标准)中了,但预编译(
#include
) 部分应包含不带.h的标准头文件(例如#include <iostream>
)然后再using namespace std;
- using自定义的命名空间:
using namespace 命名空间名[ ::子命名空间名1…… ]
当只有一个字空间时,可以略去不写 [ ]
如using namespace Outer::Inner;
- 要写子命名空间而不是只写(也不用/不能额外写)基命名空间,不然很有可能引起名称冲突
- 剩下的就像使用类一样
- 标准C++库(不包括标准C库)中所包含的所有内容(包括常量,变量,结构,类和函数, etc.)都被定义在命名空间std(standard标准)中了,但预编译(
使用using声明
using 命名空间名::[子命名空间名::子子……]成员名;
- 用处相当于对于单独一个成员免去每一次都写作用域运算符的麻烦,但该命名空间下的其他成员依然要依靠作用域运算符来定位
using指令和using声明的比较
- using指令使用后,可以一劳永逸,它对整个命名空间所有成员都有效;但using声明却必须对不同成员分别声明
- 但一般来说,using声明会更加安全。因为using声明只会导入指定的名称,如果改名称与局部名称冲突,编译器会报错。而using指令导入的,包括那些根本用不到的名称,且如果其中有 名称与局部名称冲突,编译器不会发出任何警告信息,而是仅仅用局部名称覆盖命名空间中的同名成员
- Conclusion:虽然使用命名空间的方法有多种可供选择,但不能贪图方便而一味使用using指令,那样就背离了设计命名空间的初衷,也失去了命名空间本应有的防止名称冲突的功能
还没有评论,来说两句吧...