四种对象生存期和作用域、static 用法总结

C++ Primer 学习笔记_23_类与数据抽象(9)–四种对象生存期和作用域、static 用法总结

前言:

从上图可知,程序占用的内存被分了以下几部分.

(1)、栈区(stack)

存放函数的参数值,局部变量的值等,内存的分配是连续的。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁,其特点是效率高,但空间大小有限

注意:通常栈空间容量比较小,一般是1MB~2MB,所以体积比较大的对象不适合在栈中分配。

(2)、堆区(heap)

,其生命周期由,它们是不同区域的内存块通过指针链接起来的。在没有释放之前一直存在,直到程序结束,其特点是使用灵活,空间比较大,但容易出错。

(3)、静态区(全局区)(static)

。静态区的内容在总个程序的生命周期内都存在,由编译器在编译的时候分配,程序结束后由系统释放。

(4)、文字常量区

常量字符串就是放在这里的。 程序结束后由系统释放

(5)、程序代码区

存放函数体的二进制代码。

一、四种对象生存期和作用域

(1)栈对象

隐含调用构造函数(程序中没有显式调用)

(2)堆对象

隐含调用构造函数(程序中没有显式调用),要显式释放

(3)全局对象、静态全局对象

全局对象的构造先于main函数

已初始化的全局变量或静态全局对象存储于.data段中

未初始化的全局变量或静态全局对象存储于.bss段中

(4)静态局部对象

已初始化的静态局部变量存储于.data段中

未初始化的静态局部变量存储于.bss段中

注意:箭头的方向的意思是,栈是由高地址向低地址扩展,堆是由低地址向高地址扩展

【例子】

#include <iostream>using namespace std;class Test{public:Test(int n) : n_(n){cout << "Test " << n_ << " …" << endl;}~Test(){cout << "~Test " << n_ << " …" << endl;}private:int n_;};int n; // 未初始化的全局变量,初始值为0。n存储于.bss段中。(block started by symbol)int n2 = 100; // 已初始化的全局变量,初始值为100。n2存储于.data段中。Test g(100); // 全局对象的构造先于main函数static Test g2(200);int main(void){cout << "Entering main …" << endl;Test t(10);// 栈上创建的对象,在生存期结束的时候自动释放{Test t(20);}{Test *t3 = new Test(30);// 堆上创建的对象,要显式释放delete t3;}{static int n3;// n3存储于.bss段中 (编译期初始化)static int n4 = 100; // n4存储于.data段中 (编译期初始化)static Test t4(333); // t4对象运行期初始化 .data段}cout << "Exiting main …" << endl;}

运行结果:

Test 100 …Test 200 …Entering main …Test 10 …Test 20 …~Test 20 …Test 30 …~Test 30 …Test 333 …Exiting main …~Test 10 …~Test 333 …~Test 200 …~Test 100 …

二、static 用法总结

(1). 用于函数内部修饰变量,即函数内的静态变量。这种变量的生存期长于该函数,使得函数具有一定的“状态”。使用静态变量的函数一般是不可重入的,也不是线程安全的,比如strtok(3)。(2). 用在文件级别(函数体之外),修饰变量或函数,表示该变量或函数只在本文件可见,其他文件看不到也访问不到该变量或函数。C语言的这两种用法很明确,一般也不容易混淆。

由于C++引入了类,在保持与C语言兼容的同时,static关键字又有了两种新用法:(3).用于修饰类的数据成员,即所谓“静态成员”。这种数据成员的生存期大于class的对象(实例/instance)。静态数据成员是每个class有一份,普通数据成员是每个instance 有一份。(4). 用于修饰class的成员函数,即所谓“静态成员函数”。这种成员函数只能访问静态成员和其他静态成员函数,不能访问非静态成员和非静态成员函数。

1、static在程序中三种用法

(1)static在函数或全局只对当前文件下可见

(2)static在类中只属于一个类而不属于特定对象,或对象的变量和函数

(3)statci在头文件中作用域只在定义了该头文件的c/cpp文件中,其他有同一头文件是不可见的。(在网上看到一个说法,不一定对,这样定义有一定的危害性:头文件包含多次,变量就定义了多少次,容易重复定义,因此不建议在头文件定义static。)

2、不考虑类,static的作用

(1)第一个作用:隐藏

当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。比如,同时编译两个源文件,a.cpp和main.cpp,下面时a.cpp的内容:

这里的风景美不胜收,真让人流连忘返。

四种对象生存期和作用域、static 用法总结

相关文章:

你感兴趣的文章:

标签云: