C++ Primer 有感(命名空间)
1.命名空间定义以关键字namespace开始,后接命名空间的名字。
2.命名空间可以在全局作用域或其他作用域内部定义,但不能在函数或类内部定义。
3.定义在命名空间中的实体称为命名空间的成员。像任意作用域的情况一样,命名空间中的每个名字必须引用该命名空间的唯一实体。
4.与其他作用域不同,命名空间可以在几个部分中定义。命名空间由它的分离定义部分的总和构成,命名空间是累积的。一个命名空间的分离可以分散在多个文件中,在不同文本文件中的命名空间定义也是累积的。
5.在命名空间的内部定义的函数可以使用同一命名空间中定义的名字的简写形式。也可以在命名空间定义的外部定义命名空间成员,用类似于在类外部定义类成员的方式:名字的命名空间声明必须在作用域中,并且定义必须指定该名字所属的命名空间。
6.虽然可以在命名空间定义的外部定义命名空间成员,对这个定义可以出现的地方仍有些限制,只有包围成员声明的命名空间可以包含成员的定义。
7.定义在全局作用域的名字是定义在全局命名空间中的。全局命名空间是隐式声明的,存在于每个程序中。因为全局命名空间是隐含的,它没有名字,所以记号::member_name引用全局命名空间的成员。
8.一个嵌套命名空间即是一个嵌套作用域——其作用域嵌套在包含它的命名空间的内部。嵌套命名空间中的名字遵循常规规则:
(1)外围命名空间中声明的名字被嵌套命名空间中同一名字的声明所屏蔽;
(2)嵌套命名空间内部定义的名字局部于该命名空间;
(3)外围命名空间之外的代码只能通过限定名引用嵌套命名空间中的名字。
9.命名空间可以是未命名的,未命名的命名空间在定义时没有给定名字。未命名的命名空间以关键字namespace开头,接在关键字namespace后面的是由花括号定界的声明块。
10.未命名的命名空间与其他命名空间不同,未命名空间的命名空间的定义局部于特定文件,从不跨越多个文本文件。每个文件有自己的未命名的命名空间。
11.未命名的命名空间用于声明局部于文件的实体。在未命名的命名空间中定义的变量在程序开始时创建,在程序结束之前一直存在。
12.未命名的命名空间中定义的名字可以直接使用,毕竟,没有命名空间名字来限定它们。不能使用作用域操作符来引用未命名的命名空间的成员。
13.未命名的命名空间中定义的名字只在包含该命名空间的文件中可见。如果另一个文件包含一个未命名的命名空间,两个命名空间不相关。两个命名空间可以定义相同的名字,而这些定义将引用不同的实体。
14.未命名的命名空间中定义的名字可以在定义该命名空间所在的作用域中找到。如果在文件的最外层作用域中定义未命名的命名空间,那么未命名的命名空间中的名字必须与全局作用域中定义的名字不同:
inti; namespace{ int i; }; //error:ambiguousdefined globally and in an unnested,unnamed namespace i =10;
15.未命名的命名空间也可以嵌套在另一命名空间内部。如果未命名的命名空间是嵌套的,其中的名字按常规方法使用外围命名空间名字访问:
namespace local{ namespace{ int i; } } local::i= 42;
16.如果头文件中定义了未命名 的命名空间,那么,在每个包含该头文件的文件中,该命名空间中的名字将定义不同的局部实体。
17.一个using声明一次只引入一个命名空间成员,它使得无论程序中使用哪些名字,都能够非常明确。
using std::map; using std::pair; using std::size_t; using std::string;
18.using声明中引入的名字遵循常规作用域规则。从using声明开始,直到包含该using声明的作用域的末尾,名字都是可见的。外部作用域中定义的同名实体被屏蔽。
简写名字只能在声明它的作用域及其嵌套作用域中使用,一旦该作用域结束了,就必须使用完全限定名。
using声明可以出现在全局作用域、局部作用域或者命名空间作用域中。类作用域中的using声明限于被定义类的基类中定义的名字。
19.可用命名空间的别名将较短的同义词与命名空间名字相关联:
namespace cplusplus_primer { /*.....*/ } namespace primer = cplusplus_primer;
命名空间别名声明以关键字namespace开头,接命名空间的别名,再接=,再接原来的命名空间的名字和分号。如果原来的命名空间名字是未定义的,就会出错。一个命名空间可以有许多别名,所有别名以及原来的命名空间名字都可以互换使用。
20.using指示使我们能够使用命名空间名字的简写形式。与using声明不同,using指示无法控制使得哪些名字可见——它们都是可见的。
21.using指示以关键字using开头,后接关键字namespace,再接命名空间名字。using指示使得特定命名空间的所有名字可见,没有限制。
22.当类包在命名空间中的时候,发生相同的查找:首先在成员总找,然后在类(包括基类)中找,再在外围作用域中找,外围作用域中的一个或多个可以是命名空间:
namespace A{ int i; int k; class C1{ public: C1( ):i(0),j(0) { } int f1() { return k; //return A::k } int f2() { return h; //error:h is not defined } int f3(); private: int i; //hides A::i within C1 int j; }; int h = i; // initialized from A::i } intA::C1::f3() { return h; //OK:return A::h }
除了成员定义例外,总是向上查找作用域:名字在使用之前必须声明。因此,f2中的return语句将不能编译,它试图引用命名空间A中的名字h,但h还没有定义。如果使A中的名字在C1的定义之前定义,h的使用就是合法的。类似的,f3内部对h的使用时正确的,因为f3定义在已经定义了A::h之后。