C++中static的两种新用法

[复制链接]

1234

主题

-8

回帖

216

积分

游客

积分
216
a420995601 发表于 2018-12-23 01:50:21 | 显示全部楼层 |阅读模式
  C++中static的两种新用法
  在C语言中,static的用法非常简单,只有两种:
  (1)用于函数内部修饰变量,即函数内的静态变量。这种变量的生存期大于函数,使得函数具有一定的“状态”,使用静态变量的函数一般是不可重入的,也不是线程安全的。如strtok(3).
  (2) 用在文件级别,函数体外, 修饰变量或函数,表示该变量或函数只在本文件内可见。其它文件看不到也访问不到该变量或函数。
  在C++中,保留了C的上面用法,除此以外,还有以下两种新用法:
  (1) 用于修饰类的数据成员,即所谓的“静态成员”, 这种数据成员的生存期大于类对象(实例),静态数据成员是每个class有一份, 普通数据成员是每个类对象(实例)有一份。
  (2) 用于修饰类的成员函数,即所谓的“静态成员函数”,这种成员函数也只能访问静态成员和其它静态成员函数,不能访问非静态成员与非静态成员函数。
  关于对象的作用域与生存期
  需要明确一点的是,作用域与生存期在某些情况下是不一致的,它们并不等同。下面是存储器模型:
  程序在存储器中按上述模型存放,它有代码段,数据段,堆和栈之分。代码段是只读的,数据段分为未初始化的数据段.bss(block started by symbol)和已初始化的数据段.data段。未初始化数据段.bss的特征是在可执行文件中不占空间,在运行时才分配空间,而.data段在编译期间就被初始化,在可执行文件中占据空间 捕鱼游戏 星力捕鱼
  对于全局变量
  如int a; 未被初始化,所以它存放在.bss段中
  如int a = 100; 已初始化,故它存放在.data段中.
  对于静态全局变量
  如static int a; 未被初始化,它存放在.bss段中
  如static int a = 100; 已初始化,故它存放在.data段中
  对于静态局部变量
  如下所示:
  int main()
  {
  ...
  {
  //下面a,b的作用域在{}内,生存期在整个程序的生存期之内
  static int a; //存储于.bss段中
  static int b = 100; //存储于data段中。
  }
  }
  对于全局对象与静态全局对象
  如Test g(10); static Test g(10); 它们存放在data段中,但运行时,对象的构造函数都是先于main函数调用的,在main函数结束后自动调用析构函数销毁
  对于局部对象
  int main()
  {
  ....
  Test t(10);//局部对象在栈上创建,生存期在main块作用域范围之内,main结束后自动调用析构函数销毁
  }
  如果在以下情况,它将在{}作用域结束后就自动调用析构函数销毁
  int main()
  {
  ...
  {
  Test t(10); //在栈上创建,作用域在{}
  }//退出{}后就自动销毁对象
  }
  对于静态局部对象
  如下:
  int main()
  {
  ...
  {
  //均存储在data段中,作用域在{}之内,生存期在整个main结束后才自动调用析构函数销毁。
  static Test t(100);
  static Test t2;
  }
  }
  对于堆上的对象
  如下:
  int main()
  {
  ...
  {
  Test *t3 = new Test(20); //堆上创建的对象,即使跳出作用域{}也不能自动调用析构函数来释放对象。可见作用域与生存期是不同的。作用域仅仅是对象的可见范围。
  delete *t3; //主动析构。
  }
  }
  总而言之,静态全局对象,全局对象,静态局部对象都存储在data段中,静态全局对象与全局对象先于main函数调用构造函数,但它们三个都在main结束后自动调用析构函数销毁对象。堆上对象创建于堆,离开作用域范围后依旧不会自动销毁,需要手动销毁对象。局部对象创建于栈上,离开作用域后自动销毁。只有全局的普通变量才区分.bss段与.data段,未被初始化的全局变量存放在.bss段中,初始化的全局变量存放在data段中,全局变量作用域在整个程序的生命周期。局部变量在栈上创建,作用域在局部。另外切记,作用域与生存期有时并不等同。

你喜欢看
  • python如何操作Sql Server 2008

      python如何操作Sql Server 2008   最近由于公司的一个项目需要,需要使用Sql Server 2008数据库,开 ...

  • linux内核如何管理进程

      linux内核如何管理进程   “进程”有诸多的定义,在许多的教材资料上,其定义是一个程序的执行实例, ...