关于namespace:
在头文件中,不要把#include命令放在命名空间中,命名空间中的内容不包括命令行,否则编译会出错。
命名空间可以在全局作用域或其他作用域内部定义,但不能在函数或类内部定义。
标准命名空间std
标准C++库的所有标识符都是在一个名为std的命名空间中定义的,或者说标准头文件(如iostream)中函数、类、对象和类模板是在命名空间 std中定义的。
全局命名空间
全局命名空间是隐式声明的,使用记号
::namespace_member
引用全局命名空间的成员。定义命名空间成员
定义在命名空间内的实体称为命名空间成员。
可以在命名空间内部定义,也可以在命名空间外部定义,在外部定义时必须指定该名字所属的命名空间。
命名空间可以是不连续的,命名空间的分离部分可以分散在多个文件中。
利用该特征将接口和实现分离:
- 定义类的命名空间成员,以及作为类接口的一部分的函数声明与对象声明,可以放在头文件中,使用命名空间成员的文件可以包含这些头文件
命名空间成员的定义可以放在单独的源文件中。
举例:
//Sale_item.h namespace cplusplus_primer{ class Sale_item{}; Sale_item operator+(const Sale_item&,const Sale_item&); }
//Query.h namespace cplusplus_primer{ class Query{ public: Query(); std::ostream &display() const; ... }; class Query_base{}; }
//Sale_item.cpp #include"Sale_item.h" namespace cplusplus_primer{ //definitions for sale_item members and overloaded operators(如:operator+) }
//Query.cpp #include"Query.h" namespace cplusplus_primer{ //definitions for Query members and related functions(如:display) }
在声明一个命名空间时,花括号内可包括以下类型:
- 变量(可以带有初始化)
- 函数(可以是定义或声明)
- 结构体和类(成员函数可以在命名空间的类的内部定义,也可以在命名空间的实现文件中定义)
- 模板
- 命名空间(嵌套的命名空间)
使用命名空间的方法:
使用命名空间别名
可以为命名空间起一个别名(namespace alias),用来代替较长的命名空间名。如
namespace Television //声明命名空间
可以用一个较短而易记的别名代替它。如:
namespace TV=Television; //别名TV与原名Television等价
也可以说,别名TV指向原名Television,在原来出现Television的位置都可以无条件地用TV来代替。
使用
using 命名空间成员名
- using后面的命名空间成员名必须是由命名空间限定的名字。例如:
using nsl::Student; //在用上面的using声明后,在其后程序中出现的Student就是隐含地指nsl::Student
以上语句声明:在本作用域(using语句所在的作用域)中会用到命名空间ns1中的成员Student,在本作用域中如果使用该命名空间成员时,不必再用命名空间限定。
- using声明的有效范围是从using语句开始到using所在的作用域结束。
使用
using namespace 命名空间名
格式:
using nanlespace ns1; //声明了在本作用域中要用到命名空间nsl中的成员,在使用该命名空间的任何成员时都不必用命名空间限定。
C++还允许使用没有名字的命名空间,
如在文件A中声明了以下的无名命名空间:
namespace //命名空间没有名字 { void fun( ) //定义命名空间成员 { cout<<"OK."<<endl; } }
由于命名空间没有名字,在其他文件中显然无法引用,它只在本文件的作用域内有效。