需要注意局部自动对象具有自动存储周期,它们在栈区被分配存储空间;静态和全局对象具有静态存储周期,它们在全局数据区分配存储空间;这些对象由编译器负责内存的分配和回收,程序员无法控制内存分配和回收的时刻及内存的大小(存储在堆区(也叫动态内存区或自由存储区)的对象可以由程序员控制)。
对象的4类生命期
存储周期表明了对象可以在内存里存储的时间,C++支持以下4种类型的存储周期:
a.自动存储周期:
定义在函数体或者语句块内部的对象(包括函数的形参)具有自动存储周期,即在程序执行
到其定义的位置时在内存中创建,离开其作用域时被释放。
b.静态存储周期:
定义在函数外面或者使用staic关键字声明的对象具有静态存储周期,即在程序运行期间,
它们始终存在,直到程序结束。
c.动态存储周期:
利用运算符new生产的对象具有动态存储周期,可以利用运算符delete释放其内存空间,
也就是说,它们的存储周期具有从new操作开始,到delete操作结束。
d.线程存储周期:
为了支持并行程序设计,C++11引入了thread_local关键字,利用thread_local创建的对
象的存储周期在其所在的线程创建时开始,在线程结束时结束。
在程序运行期间,存储周期类型不同的对象在不同的内存区域被分配存储空间。具有自动存储周期的对象在栈区被分配存储空间,具有静态存储周期的对象在全局数据区被分配存储空间,而具有动态存储周期的对象则在堆区被分配存储空间。
一个对象的生命期是指在其存储周期内可以访问该对象的时间(该时间通常为一个对象从产生到消亡的时间)。需要注意的是存储周期类型相同的对象不一定有相同的生命期,如在一个块内先定义的对象的生命期要早于后面定义的对象。
对象的2类作用域
a.局部作用域:
只能在函数/语句块内部可见/访问。
b.全局作用域:
从定义处到其所在的文件末尾都是可见/可访问的,因此也称为文件域。具有外链接性的对
象,当在其他文件中比如main.cpp使用extern声明后,其作用域可以被扩展到main.cpp,即
在main.cpp也可以访问它。
对象的3类链接性
a.无链接性:
只能够在其定义域内部访问,不可以在其他的作用域访问。
b.内部链接性:
只能在其定义的文件中被访问,不可以在其他文件中被访问。
c.外部链接性:
不仅可以在其定义的文件中被访问,还可以在其他的文件中被访问。
局部对象(在语句块内部定义的对象,包括函数形参)和全局对象(在函数外面定义的对象)
局部对象都具有局部作用域,比如在函数func内定义的局部自动变量和局部静态变量都只能在函数func内部访问/可见。但是它们有不同类型的存储周期,其中的局部自动对象具有自动存储周期,局部静态对象(用static定义的对象,如果没有显式初始化则被默认初始化为0)具有静态存储周期。另外局部对象无链接性。
全局对象具有全局作用域,和具有静态存储周期。对于内置类型的全局对象,如果没有显式初始化则被默认初始化为0
int a = 10; //定义全局对象
int main () {
int a = 1; //定义局部自动变量
cout << a << endl; //访问局部自动变量a,打印1
cout << ::a << endl; //访问全局对象a,打印10。::为全局作用域符
}
另外全局对象具有外部链接性,可以利用关键字static来限制一个全局对象只能在其定义的文件中被访问,使其具有内部链接性。例如在源文件fun.cpp中定义一个全局对象:
int b = 10; //b具有外部链接性
对象b具有外部链接性,可以在其他文件中被访问。在main.cpp中,可以通过extern声明来访问b,例如:
/*通过extern声明后,b的作用域从fun.cpp扩展到了main.cpp文件中,因此
在main.cpp中也可以访问它。*/
extern int b;
/*c具有内部链接性,其作用域被限制在main.cpp文件,不能在其他文件中访问它。*/
static int c = 20;