//1.异常:待研究 //2.命名空间: // A:多个库将名字放置在全局命名空间中将引发命名空间污染。 // B:命名空间为防止名字冲突提供了更加可控的机制。命名空间分割了全局命名空间,其中每个命名空间都是一个作用域。 // C:一个命名空间的定义包含两个部分:首先是关键字namespace,随后是命名空间的名字。只要是能出现在全局作用域中的声明就能置于命名空间中,主要为:类,变量(及其初始化操作),函数,模板和其它命名空间。 // D:命名空间不能定义在函数或类的内部,可以定义在全局命名空间和其它命名空间中。 // E:命名空间作用域后面无需分号。 // F:命名空间可以定义在几个不同的部分。形如: namespace szn{}可能定义了一个名为szn的新命名空间,也可能是为已经存在的命名空间添加新的成员。如类的声明和定义应该分开置于不同的文件,则当类位于命名空间时就可方便的声明与定义了。 // G:允许在命名空间中声明一个成员而在命名空间所属的外层空间中进行定义。 // H:全局作用域中定义的名字也就是定义在全局命名空间中。全局命名空间以隐式的方式声明,并且在程序中都会存在,全局作用域中定义的名字被隐式添加到全局命名空间中。 // I:作用域运算符同样可以作用于全局作用域的成员,因为全局作用域是隐式的,所以其没有名字,形如 ::member_name; // J:未命名的命名空间:是指关键字namespace后紧跟花括号扩起来的一系列声明语句。未命名的命名空间中定义的变量具有静态生命周期。一个未命名的命名空间不能跨越多个文件。每个文件定义了自己的未命名的命名空间。 // 如果一个头文件定义了未命名的命名空间,则该命名空间中的定义的名字将在每个包含了该头文件的文件中对应不同实体。如果一个头文件定义了一个static变量,则包含此头文件的源文件都将拥有对应的不同实体 // 在文件中进行静态声明的做法应该是:使用未命名的命名空间。使用static的做法是继承与C语言,已经被未命名的命名空间所取代。 // K:命名空间的别名使得我们可以为命名空间的名字设定一个短的多的同义词。 namespace szn{} namespace s = szn; //令s称为命名空间szn的别名 // L:using声明:一条using声明语句一次引入命名空间的一个成员,其有效范围是从using声明开始的地方一直到using声明所在的作用域结束为止。在此过程中,外层作用域的同名实体将被隐藏。在类中,这样的声明语句只能指向基类的成员,并改变其访问权限。 // 注意点:using只作用于一个名字。当命名空间szn存在多个名为fun的重载函数时,当使用using szn::fun;会将fun的所有重载版本均添加到使用using声明的作用域中。 // 一个using声明引入的函数将重载该声明语句所属作用域中声明的其他同名函数。如果using声明出现在局部作用域中,则引入的名字将隐藏外层作用域的相关声明。如果using声明所在的作用域中已经有一个函数与新引入的函数完全相同则会引发错误。 // M:using指示:以关键字using开始后接关键字namespace以及命名空间的名字。using指示使得特定的某个命名空间中的所有名字都可见。这就有可能导致名字冲突问题。在命名空间本身的实现文件中可以使用using指示,或者在一个函数的内部使用using指示,其他情况慎用。 // 使用using指示,实际上是将被操作的命名空间中的成员提升到最近的外层作用域中。 // 与using声明不同的是:对于using指示来说,引入一个与已有函数完全相同的函数并不会出错,此时只要我们指明当前调用的函数是来自命名空间的版本还是当前作用域的版本即可。 namespace szn {int value;} int value; int _tmain(int argc, _TCHAR* argv[]) { //using指示 using namespace szn; //实际上是将命名空间szn中的成员提升最近的外层作用域即全局作用域中,从而产生了名字冲突 int v = value; //二义性 return 0; } namespace szn {int value = 10;} int value; int _tmain(int argc, _TCHAR* argv[]) { //using声明 using szn::value; //使用using声明则是将指定命名空间中的指定名字添加入当前作用域,不会产生名字冲突。 int v = value; //v = 10 return 0; } namespace szn {void fun(){printf("szn_0 ");}} //using szn::fun; //将报错 using namespace szn; //不会报错 void fun(){printf("szn_1 ");} // N:命名空间内部名字的查找规则: 即由内向外依次查找每个外层作用域。 // 对于位于命名空间中的类来说,常规的查找规则仍然适用:当成员函数适用某个名字时,首先在该成员中查找,然后在类中查找(包括基类),最后在外层作用域中查找。 // 对于命名空间中名字的隐藏规则来说有一个重要的例外:当我们给函数传递一个类类型对象、指针、引用时,除了在常规的作用域中查找外还会查找实参类所属的命名空间。 namespace szn { class CTest {public: int value;}; void SetAndPrintfCTest(CTest &Test){Test.value = 10; printf("%d ", Test.value);} } szn::CTest Test; SetAndPrintfCTest(Test); //这里无需使用szn::限定符和using声明就可以调用SetAndPrintfCTest //3.多重继承与虚继承:待研究