网2:20A01 第六章名称空间 本章主要内容 1.名称冲突 2.内部连接与外部连接 3.名称空间的定义和使用
22:20:01 第六章 名称空间 本章主要内容 1. 名称冲突 2. 内部连接与外部连接 3. 名称空间的定义和使用
网2:20A01 §1名称冲突 与标识符的作用范围相关:在同一个作用域内,不能有两 个完全一样的标识符 工程中包含多个文件时,由于有些标识符的作用范围是可 以扩展的,因此会造成标识符的名称冲突 >团队开发中,不同模块由不同程序员完成,各人都有自己 给标识符命名的习惯,不同模块中的标识符之间可能存在 名字上的冲突 例:变量名的冲突 同一工程中的文件 //main. cpp /def var cpp //another. cpp extern int nTestvar void maino int nTest Var,int nTest Var, nTestvar 连接时无法确定是哪一个文件中 定义的变量 nTestvar
22:20:01 §1 名称冲突 ➢与标识符的作用范围相关:在同一个作用域内,不能有两 个完全一样的标识符 ➢工程中包含多个文件时,由于有些标识符的作用范围是可 以扩展的,因此会造成标识符的名称冲突 ➢团队开发中,不同模块由不同程序员完成,各人都有自己 给标识符命名的习惯,不同模块中的标识符之间可能存在 名字上的冲突 例:变量名的冲突 //main.cpp extern int nTestVar; void main() { nTestVar = 0; } //defvar.cpp int nTestVar; //another.cpp int nTestVar; 连接时无法确定是哪一个文件中 定义的变量nTestVar 同一工程中的文件
网2:20A01 例:函数名的冲突 同一工程中的文件 void funcTesto //defvar. cpp //another. cpp void maino void funcTesto void funcTest OI functes 0 } 函数重复定义 连接时无法确定是哪一个文件中定义的函数 unrEst0; 待开发的系统越大,名字的冲突越严重 一旦发生名字的冲突,会造成对源代码的大量修改,增大 了开发工作量,且在修改过程中可能引入新的错误 在团队开发中,这种情况尤其严重
22:20:01 例:函数名的冲突 void funcTest(); void main() { funcTest(); } //defvar.cpp void funcTest() { } //another.cpp void funcTest() { } 同一工程中的文件 连接时无法确定是哪一个文件中定义的函数funcTest(); ➢待开发的系统越大,名字的冲突越严重 ➢一旦发生名字的冲突,会造成对源代码的大量修改,增大 了开发工作量,且在修改过程中可能引入新的错误 ➢在团队开发中,这种情况尤其严重 函数重复定义
§2内部连接与外部连接 源程序必须翻译成二进制的机器代码,才能被执行 C++的翻译采用编译十连接的方式,即工程中所有源程序文 件(CPP文件)经过编译程序的处理,得到相应的目标程序 文件(0bj文件),连接程序再把这些目标程序文件与系统 提供的库函数、类等进行连接(组装),得到可执行的程序 连接程序的任务之一是建立标识符与内存地址之间的对应 关系,即确定标识符代表的变量或函数等在内存中的位置 根据标识符的属性不同,连接方式有两种 内部连接 外部连接
22:20:01 §2 内部连接与外部连接 ➢源程序必须翻译成二进制的机器代码,才能被执行 ➢C++的翻译采用编译+连接的方式,即工程中所有源程序文 件(.CPP文件)经过编译程序的处理,得到相应的目标程序 文件(.obj文件),连接程序再把这些目标程序文件与系统 提供的库函数、类等进行连接(组装),得到可执行的程序 ➢根据标识符的属性不同,连接方式有两种 .内部连接 .外部连接 ➢连接程序的任务之一是建立标识符与内存地址之间的对应 关系,即确定标识符代表的变量或函数等在内存中的位置
网2:20:01 外部连接 作用域为文件范围的标识符,连接程序处理工程中的任何 个文件时,该标识符对于连接程序都是可见的,称这种 标识符具有外部连接属性 全局变量和全局函数都具有外部连接属性 具有外部连接属性的标识符可能会造成名称冲突 内部连接 静态函数、全局静态变量对应的标识符,只在定义该标识 符的文件中起作用,连接程序处理工程中其它文件时,该 标识符对连接程序是不可见的,称这种标识符具有内部连 接属性 具有内部连接属性的标识符不会与其它文件、模块中标识 符的名称发生冲突 局部变量对应的标识符只在定义它的函数中起作用,不会 与其它标识符发生冲突,所以一般不讨论其连接属性
22:20:01 ➢外部连接 ➢作用域为文件范围的标识符,连接程序处理工程中的任何 一个文件时,该标识符对于连接程序都是可见的,称这种 标识符具有外部连接属性 ➢全局变量和全局函数都具有外部连接属性 ➢具有外部连接属性的标识符可能会造成名称冲突 ➢内部连接 ➢静态函数、全局静态变量对应的标识符,只在定义该标识 符的文件中起作用,连接程序处理工程中其它文件时,该 标识符对连接程序是不可见的,称这种标识符具有内部连 接属性 ➢具有内部连接属性的标识符不会与其它文件、模块中标识 符的名称发生冲突 局部变量对应的标识符只在定义它的函数中起作用,不会 与其它标识符发生冲突,所以一般不讨论其连接属性
例:外部连接与内部连接 网2:20A01 //fTest1 cpp int cOnflict. 冲突:外部连接 static int nnoconflic void func Conflicto i static void funcNoConflieto //fTest2 cpp int cOnflict 不冲突:内部连接 static int nNoConf1ict void func Conflict O static void funcNoConflioto( main. cpp void血ai0{ extern int cOnflict cOnflict =13 extern int nNoConf1i ct; nNoCofflict=2;//4H void func Conflict O func Conflict O void func NoConf lictO; func NoConflictO;/*4H*/J
22:20:01 例:外部连接与内部连接 //fTest1.cpp int nConflict; static int nNoConflict; void funcConflict(){ } static void funcNoConflict(){ } //fTest2.cpp int nConflict; static int nNoConflict; void funcConflict(){ } static void funcNoConflict(){ } //main.cpp extern int nConflict; extern int nNoConflict; void funcConflict(); void funcNoConflict(); void main(){ nConflict = 1; nNoConflict = 2; //错 funcConflict(); funcNoConflict(); /*错*/ } 冲突:外部连接 不冲突:内部连接
§3名称空间( names ce) 名称空间在C++中是为了对全局标识符的名称进行灵活 高效的管理和使用而引入的概念 把一个全局的名称空间分成多个小空间,每个全局标识符 对应的名字都属于其中某个名称空间,不同名称空间中的 标识符可以同名,但因所在空间不同(作用范围不同)而不 会发生冲突,从而解决了名称冲突的问题
22:20:01 §3 名称空间(namespace) ➢名称空间在C++中是为了对全局标识符的名称进行灵活、 高效的管理和使用而引入的概念 ➢把一个全局的名称空间分成多个小空间,每个全局标识符 对应的名字都属于其中某个名称空间,不同名称空间中的 标识符可以同名,但因所在空间不同(作用范围不同)而不 会发生冲突,从而解决了名称冲突的问题
网2:20:01 1.名称空间的创建:与创建一个类相似 例: namespace myLib{ class x: void funcTesto(K 说明: 定义 namespace的}后不加分号”;” 名称空间内部可以包含类、普通函数、全局变量等全局标 识符的定义或声明,也可以包含名称空间的嵌套定义 > namespace只能在全局范围内定义 名称空间是开放的,一个 names pace可以在多个头文件中 用同一个标识符定义,该名称空间将是这多个定义的并集 名称空间不是数据类型,不能定义名称空间的变量
22:20:01 1. 名称空间的创建:与创建一个类相似 例:namespace MyLib{ class X{ }; void funcTest(){ } } 说明: ➢定义namespace的}后不加分号”;” ➢名称空间内部可以包含类、普通函数、全局变量等全局标 识符的定义或声明,也可以包含名称空间的嵌套定义 ➢namespace只能在全局范围内定义 ➢名称空间是开放的,一个namespace可以在多个头文件中 用同一个标识符定义,该名称空间将是这多个定义的并集 ➢名称空间不是数据类型,不能定义名称空间的变量
例:名称空间的定义 网2:20A01 //classX. h namespace MyLib class classX int x, public classx(int xx) void show O //classX. cpp #inc1ude“c1assX,h” using namespace MyLib; classX:: classx(int xx) void classX:: show O [cout < x<< end1
22:20:01 //classX.cpp #include “classX.h” MyLib::classX::classX(int xx) { x=xx; } void MyLib::classX::showX() { cout << x << endl; } //classX.cpp #include “classX.h” using namespace MyLib; classX::classX(int xx) { x = xx; } void classX::showX() { cout << x << endl;} 例:名称空间的定义 //classX.h namespace MyLib{ class classX{ int x; public: classX(int xx); void showX(); }; }
2:20:01 /classY. h namespace MyLib class classy i int y, public: classy(int yy) void showY O //classY. cpp # include“c1assY.h” using namespace MyLib; classY:: classY(int yy) [y=yy, I void classy:: showY O I cout < y < end1;
22:20:01 //classY.cpp #include “classY.h” MyLib::classY::classY(int yy) { y=yy; } void MyLib::classY::showY() { cout << y << endl;} //classY.cpp #include “classY.h” using namespace MyLib; classY::classY(int yy) { y = yy; } void classY::showY() { cout << y << endl; } //classY.h namespace MyLib{ class classY{ int y; public: classY(int yy); void showY(); }; }