c++存储持续性和链接性
数据存储有两个问题要解决:存多长时间,谁可以访问。这涉及3个方面:存多长时间,涉及存储持续性、谁可以访问,涉及作用域以及链接性。
持续性:
存多长时间(持续性):自动存储,静态存储、线程存储,动态。
谁可以访问:一种控制访问权的方式。涉及作用域和链接性。
说到访问方式,大的程序,都是多文件组织方式:头文件和源代码文件。多文件就涉及链接性。一个文件就是作用域。
头文件主要用于写: 函数原型(函数定义和主文件或其它要调用该函数的文件。结构声明(大家都会引用的文件)、类、模板等声明类。符号常量。内联函数。
源代码文件:函数调用或函数定义。
作用域和链接性
作用域:名称在文件(翻译单元)的多大范围可见,分为:部分和全局。部分:表示只有{}括起来的代码块内可用。全局:表示在变量定义位置到文件结束都可用。
全局作用域是名称空间作用域的一个特例。
链接性:名称在不同单元(文件)间共享方式,分为:外部的和内部的。外部的:表示在文件之间可共享。内部的:表示只在一个文件中共享。
链接性的区分:
外部:在代码块之外声明。内部:在代码块之外声明,且使用static限定。无链接性:在代码块内部,且使用static限定。
链接性为内部的全局变量:代码块之外声明的,const限定的变量,链接性也是内部的。这也是为什么可以将常量定义放在头文件中的原因。
定义和声明的区别:定义会分配存储空间,声明不会分配空间。
链接性为外部的变量,要是在别的文件中使用,要先用extern关键字声明(注意:是声明,不是定义,区别就是声明不会赋值。定义有赋值这个操作)。
关于函数的链接性
函数的存储是静态的,链接默认是外部的,可以在文件之间共享。在原型和定义时,都使用static进行说明,可以定义链接性为内部。
名称空间
了解之前,要先知道两个概念:声明区域、潜在作用域。
名称空间就是提供了一个声明名称的区域。
默认情况下,名称空间是外部链接性的,属于全局变量,可以嵌套。名称空间不能定义在代码块中。默认有一个全局名称空间,就是没有定义在任何代码块中的名称,其实是在全局名称空间里的,只是没让我们意识到。
using声明和using编译指令:区别就是一个是导入一个,一个是批量导入。声明只是导入某一个具体的名称到当前区域。编译指令是批量导入名称到当前区域。
总结
关于名称的存储,要打开思维,不要局限在变量这一个名称里,名称包括很多,变量,常量,函数,类的定义等。有名称的都在考虑范围里。这是我自己在读这章的时候思维调整不过来的地方,潜意识里总是不能联想到变量,或者只想到变量,没有想到函数,类这些。导致思考问题时容易出错,思维混乱。
关于变量,我们关心的就是,多个文件时,这个文件里的变量,那个文件里能不能用。有时我们希望另一个文件能用它,有时候我们希望另一个文件不能用它。
要解决这个关心,熟悉名称的链接性就可以了,外部链接性的,在别一个文件就可以用。用的时候用extern声明一下就可以了。
其它的,在{}内声明的变量,在{}外一律不能用。记住这一点,就不会有什么冲突的了,搞不清,就定义在{}里。
名称空间,简单说,就是给了一个独立的区域来声明。避免莫名其妙在哪里冲突了,这个模块的变量,自己定义个名称空间,所有的变量、函数、等名称都定义在这个空间里,这样就不会冲突了。名称空间是外部的,用作用域解析运算符::来使用就可以了。