四种对象生存期和作用域
程序内存空间: 代码段,数据段,堆栈段
文本段。存储可执行文件的指令;也有可能包含一些只读的常数变量,例如字符串常量等。
栈对象
隐含调用构造函数
堆对象
全局对象
全局对象的构造先于main函数,对象在运行期间初始化,变量在编译器初始化
。
已初始化的全局变量存储于.data段中
未初始化的全局变量存储于.bss段中
静态对象(全局变量与局部变量)
已初始化的静态变量存储于.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段中
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用法总结
用于函数内部修饰变量,即函数内的静态变量。
这种变量的生存期长于该函数
,使得函数具有一定的“状态”。使用静态变量的函数一般是不可重入的,也不是线程安全的
。用在文件级别(函数体之外),修饰变量或函数,表示
该变量或函数只在本文件可见
,其他文件看不到也访问不到该变量或函数。全局变量,一般在.c文件中定义
。若在.h文件定义会出现重复定义的情况。其他文件中使用全局变量,需要加extern申明
。
由于C++引入了类,在保持与C语言兼容的同时,static关键字又有了两种新用法:
用于修饰类的数据成员,即“静态成员”。这种数据成员的
生存期大于class的对象
。静态数据成员是每个class有一份,普通数据成员是每个instance 有一份。用于修饰class的成员函数,即“静态成员函数”。这种成员函数
只能访问静态成员和其他静态成员函数
,不能访问非静态成员和非静态成员函数。