C++中的生存期和作用域

原创 2006年05月27日 09:18:00

生存期和作用域,究竟有什么样的关系呢?

先解释一下生存期吧。
一个进程对应的内存空间中,包含5种不同的数据区。
按照内存中从低到高的顺序,分别为:栈、堆、BSS段、数据段和代码段。
栈:存放程序临时创建的局部对象。一般VC++6.0生成的可执行文件只有1MiB多的栈。
堆:存放进程运行中被动态分配的内存段。它大小并不固定,可动态扩张或缩减。属于内存中最多的资源。
BSS段:(它是block started by symbol的缩写)存放程序中未初始化全局对象,操作系统将自动把BSS段全部置零。
数据段:存放已初始化的全局对象和静态对象。
代码段:存放可执行文件的操作指令,即可执行程序在内存中的镜像。代码段需要防止在运行时被非法修改,所以是只读的。
可以看出,只有代码段是被操作系统保护为只读的,其他地方的常量都只被编译器保护。
当然,内存中还有很多不属于数据区的,它们是不可读写的。
在栈中的数据,生存期为包含它的{};
在堆中的数据,生存期为它被free或delete释放前。
其他的数据,生存期为进程结束前。
用户定义的变量或常量,在生存期内,除非用户自行更改或被外界因素更改,否则不会被更改。

作用域则是可以直接显式使用该变量或常量的区域。
注:这只是我自己下的定义,这样堆中的数据应该是没有作用域的,因为它不能被直接显示使用(需要通过指针或引用)。
除了局部静态变量的作用域为为包含它的{}以外,其他和生存期相同。

下面做个简单的测试,写得很乱,看不下去的看结论就行了。

 


 

// File Name : life_test.cpp
// Author : keakon
// Create Date : 2006/5/26
// Last Edited Date : 2006/5/27
// 测试各种对象的生存期和作用域
// 在VC++6.0下编译运行通过
/////////////////////////////////////////
#include <iostream>
#include <string>

using std::cout;
using std::string;
/////////////////////////////////////////
class A
{
public:
 A(string const& name) : m_Name(name) {cout << m_Name << ".A::A()/n";}
 ~A() {cout << m_Name << ".A::~A()/n";}
 string const& getName() const {return m_Name;}
private:
 string m_Name;
};
/////////////////////////////////////////
A g("g");
const A g_c("g_c");
static A g_s("g_s");
const static A g_c_s("g_c_s");

const int NUM = 10; //存放指针数组的大小
/////////////////////////////////////////
void print(A const* p[])
{
 cout << "/n/n";
 for (int i = 0; i < NUM; ++i)
 {
  cout << p[i]->getName() << " :/t" << p[i] << '/n';
 }
 cout << "/n/n";
}
/////////////////////////////////////////
void printName(A const* p[])
{
 cout << "/n/n";
 for (int i = 0; i < NUM; ++i)
 {
#ifndef NDEBUG
//如果没有定义NDEBUG,跳过4、5、8和9,因为对象已被析构
//NDEBUG是VC++6.0的一个系统宏,在debug模式下未定义,在release模式下被定义
//可以看见release模式下,4、5、8和9号对象的name变成乱码
//若取消该宏,在debug模式下会出错
//这和2种模式对离开了生存期的变量的处理方式不同有关
//PS:若取消该宏,g++下可能会打出几屏幕乱码^^
  if (i == 4 || i == 5 || i == 8 || i == 9)
  {
   continue; //进入下一次for循环
  }
#endif
  cout << p[i]->getName() << " :/t" << p[i] << '/n';
 }
 cout << "/n/n";
}
/////////////////////////////////////////
void assign(A const* p[])
{
 A l("l");
 const A l_c("l_c");
 static A l_s("l_s");
 const static A l_c_s("l_c_s");
 register A r("r");

 p[0] = &g;
 p[1] = &g_c;
 p[2] = &g_s;
 p[3] = &g_c_s;
 p[4] = &l;
 p[5] = &l_c;
 p[6] = &l_s;
 p[7] = &l_c_s;
 p[8] = new A("l_h"); //不检查是否失败了,留给自己的人品去检验吧
 p[9] = &r;

 print(p);

 delete p[8];
}
/////////////////////////////////////////
namespace test
{
 const string str("keakon是帅哥=。=");

 const string& getStr()
 {
  return str;
 }

 void printStr()
 {
  cout << str << "/n/n/n";
 }
}
/////////////////////////////////////////
int main()
{
 A const* p[NUM] = {NULL}; //全赋值为NULL

 assign(p);
 printName(p);

 assign(p);
 printName(p);

 string const &pi = test::getStr(); //其实也可以用指针的,不过感觉引用更直观
 const_cast<string&>(pi) = "keakon是美女^^v"; //更改了常量,汗=。=
 test::printStr(); //输出“keakon是美女^^v”

 return 0;
}

/*
注:
1.命名时,g表全局,l表局部,c表常量,s表静态,h表堆,r表寄存器
2.下述结论使用“对象”来表示可以是变量,也可以是常量;因为我想不到有什么好词来表示
3.以下结论仅在VC++6.0中有效

结论:
1.全局对象有static属性(地址和static对象放在一起)
2.寄存器对象有auto属性(地址和auto对象放在一起)//忘记在哪本书上看见的,貌似不能对register对象取地址
3.局部非静态对象(包括常量对象、寄存器对象和堆对象)在脱离作用域后,对象的内容是随机的
4.静态对象在脱离作用域后(程序结束前),仍可以被正常访问,且内容保持不变
5.处于另一个namespace的对象也符合上述结论(这里只测试了全局对象)
6.全局或静态对象析构时,编译器可能已将其他非静态对象析构了(如cout),因此可能不会输出信息。
实际上,如果全局或静态对象有非静态的成员的话,在它析构前,它的这些成员就已经被析构了。
*/

对C++中作用域和生存期的认识

作用域,顾名思义,就是作用的区域,分为函数原型作用域,局部作用域,类作用域和命名空间作用域。它们的作用范围按此顺序变大。 生存期,顾名思义,就是生存的日期和时间,分为静态生存期和动态生存期,静态生存...
  • CSDN_LYY
  • CSDN_LYY
  • 2014年11月30日 22:27
  • 1074

c++变量的作用域、生存期和可见性

局部变量 范围:在一个函数内部定义的变量,作用范围只限于本函数体内。 生存期:程序执行到本函数才会给局部变量分配内存单元,函数执行完毕局部变量所占的存储单元就被释放 全局变量 在函...
  • xinxing__8185
  • xinxing__8185
  • 2015年07月13日 15:13
  • 1183

C++ 标识符作用域以及对象生存期

1、C++中标识符作用域: 函数原型作用域:在函数声明中形参列表左右括号之间; 局部作用域(块作用域):声明变量所在的大括号之间 类作用域:类的成员所具有的作用域 命名空间作用域:using ...
  • liang_1996
  • liang_1996
  • 2017年02月07日 19:07
  • 661

关于C变量作用域和生存期的常见问题

作用域 作用域描述了程序中可以访问一个标识符的一个或多个区域,一个C变量的作用域可以是代码块作用域、函数原型作用域,或者文件作用域。代码块是包含在一对花括号内的一 段代码,在代码块中定义的变量具有代码...
  • xgf415
  • xgf415
  • 2016年07月21日 19:12
  • 1980

下列变量中,哪些变量的生存期和作用域是不一致的?

“任何你真正想得到的一定是值得坚持的!”
  • qq_33044095
  • qq_33044095
  • 2016年10月12日 09:49
  • 800

静态变量的生存期和作用域

静态变量的生存期和作用域
  • cyblueboy83
  • cyblueboy83
  • 2010年11月24日 11:36
  • 7109

c++中全局变量,全局静态变量,局部静态变量,局部变量的作用域和生命周期

转载地址:http://blog.csdn.net/yunyun1886358/article/details/5632087   今天在论坛上看到有朋友发帖问道:既然静态全局变量与全局变量都存储在...
  • mingzhentanwo
  • mingzhentanwo
  • 2015年02月05日 10:17
  • 2810

08.作用域和生存期

变量的作用域(scope):变量起作用或有效的代码范围,空间。 变量的生存期(life time):变量存在的时间范围,时间。根据变量的作用域将变量分为全局变量和局部变量 全局变量储存在静态数据区...
  • happy_teemo
  • happy_teemo
  • 2017年03月18日 20:56
  • 270

C++回顾之static用法总结、对象的存储,作用域与生存期

关于static用法总结,对象的存储,作用域与生存期
  • ab198604
  • ab198604
  • 2014年02月13日 15:15
  • 1734

C++作用域和生存期

C++作用域和生存期一、变量的作用域和生存期 变量分为两种:局部变量和全局变量:在大括号内出现的变量的都是局部变量,其作用域是该大括号内部,其生存期也是该大括号内;在大括号外面定义的变量都是全局变量,...
  • u011092188
  • u011092188
  • 2017年02月02日 20:49
  • 217
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++中的生存期和作用域
举报原因:
原因补充:

(最多只允许输入30个字)