C++中四种对象生存期和作用域

栈对象
    隐含调用构造函数(程序中没有显示调用)

堆对象
    隐含调用构造函数(程序中没有显示调用)

全局对象、静态全局对象
    全局对象的构造先于main函数
    已初始化的全局变量或静态全局对象存储于.data段中
    未初始化的全局变量或静态全局对象存储于.bss段中

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

内存的分段方式

163448_czIn_1582989.png

#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);// 静态全局对象的构造也会先于main函数

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;
}


static及其作用域

一、面向过程设计中的static

1、静态全局变量

在全局变量之前,加上一个修饰关键字static,该变量就被定义成为一个静态的全局变量。

我们先举一个静态全局变量的例子,如下:

//Example 1
#include <iostream.h>
void fn();
static int n; //定义静态全局变量
void main()
void fn()

静态全局变量有以下特点: 

  1. 该变量在全局数据区分配内存; 

  2. 未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化); 

  3. 静态全局变量或函数在声明它的整个文件之内都是可见的,而在文件之外是不可见的,不会暴露给别的编译单元 ;

  4. 静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。
    一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静 态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。

  5. 细心的读者可能会发现,Example 1中的代码中将
    static int n; //定义静态全局变量
    改为
    int n; //定义全局变量
    程序照样正常运行。 

  6. 的确,定义全局变量可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:
    静态全局变量只能够在当前文件当中是可见的,但是不能被其它文件所使用;因此,其它文件中可以定义相同名字的变量,不会发生冲突;
    您可以将上述示例代码改为如下:

  7. /Example 2
    //File1
    #include <iostream.h>
    void fn();
    static int n; //定义静态全局变量
    void main()
  8. //File2
    #include <iostream.h>
    extern int n;
    void fn()

编译并运行Example 2,您就会发现上述代码可以分别通过编译,但运行时出现错误。

试着将
static int n; //定义静态全局变量 

改为
int n; //定义全局变量
再次编译运行程序,就可以体会到全局变量和静态全局变量之间的区别。




转载于:https://my.oschina.net/ajian2014/blog/265258

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值