[note]C++作用域、可见性与生存期

作用域

作用域的定义

作用域是一个标识符(变量、常量、函数等)在程序正文中有效的区域。

作用域分类

  1. 函数原型作用域
  2. 局部作用域(块作用域)
  3. 类作用域
  4. 全局作用域(文件作用域)
  5. 命名空间作用域。

函数原型作用域

即参数表。函数原型中的参数,其作用域始于"(",结束于")"。

例:

double area(double radius);

局部作用域

  • 函数的形参、在块中声明的标识符。

  • 一般的大括号也具有限制代码块的作用,一个大括号就是一个局部作用域。

  • 标识符的局部生存期自声明处起,限于块中,通常以“}”结束。

局部作用域举例

void fun(int a) {
   int b = a;
   cin >> b;
   if (b > 0) {
     int c;

     ......
   }
}

类作用域

域的大小界定

类的成员具有类作用域,其范围包括类体非内联成员函数的函数体。

访问控制

如果在类作用域以外访问类的成员,要通过类名(访问静态成员),或者该类的对象名、对象引用、对象指针(访问非静态成员)。

类内常量和枚举类

类内常量需要定义为

static const typename foobar = val;
//或利用枚举方式,目的都是在编译时确定好这些常量
enum {foobar = val};

枚举类型可能会发生标识符名冲突,在C++11下可以使用enum class或者enum struct,利用作用域分辨符::进行区别。

enum class egg{big,  small, large};
enum class shirt{big,  small, large};

使用时

egg choice = egg::large;
shirt FLUO= shirt::large;

可见性

可见性是从对标识符的引用的角度来谈的概念,表示从内层作用域向外层作用域“看”时能看见什么。

可见性:如果某个标识符在外层中声明,且在内层中没有同一标识符的声明,则称该标识符在内层可见

  • 如果标识在某处可见,就可以在该处引用此标识符。
  • 对于两个嵌套的作用域,如果在内层作用域内声明了与外层作用域中同名的标识符,则外层作用域的标识符在内层不可见。

应用注意事项(仅一点):
嵌套作用域的重名问题域内和域外的同名变量,标识符使用域内变量。
生存期&作用域同这个标识符的可见性没有直接关系。可见性只和嵌套作用域重名问题相关。

生存期

  • 静态生存期:只要程序开始运行,这种生存期的变量就被分配了内存,这种变量的生存期和程序的运行期相同

对应作用域问题中的文件作用域的标识符和static、enum成员

  • 局部生存期:这种变量的生存期开始于程序执行经过其声明点时,而结束于命名它的标识符所在的作用域尾(一般是}
  • 动态生存期:这种变量可以随时创建,随时删除,创建和删除是程序员用内存操作函数进行的。

以下这个例子将说明:

  1. 静态生存期意味着程序起止的寿命,不一定和全局作用域对应,如a,在other()函数内部是内层,出了函数就是外层的a。(可见性的问题)
  2. 局部生存期和局部作用域对应,如other()中的局部变量c。
  3. 各种寿命的标识符都要受到可见性的制约,a、b、c都是如此。
#include<iostream>
using namespace std;

int i = 1; // i 为全局变量,具有静态生存期。

void other() {
static int a = 2;
static int b;
// a,b为静态局部变量,具有全局寿命,局部可见。
//只第一次进入函数时被初始化。
int c = 10; // C为局部变量,具有动态生存期,
//每次进入函数时都初始化。
a += 2; i += 32; c += 5;
cout<<"---OTHER---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
b = a, c = a;
}

int main() {
static int a;//静态局部变量,有全局寿命,局部可见。
int b = -10; // b, c为局部变量,具有动态生存期。
int c = 0;
cout << "---MAIN---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
//---MAIN---
//i: 1 a: 0 b: -10 c: 0
//注意:static变量默认初始化为0

c += 8; other();
//---OTHER---
//i: 33 a: 4 b: 0 c: 15
//i具有全局作用域,所以在函数中被操作。
//b是默认初始化的static变量
//a是全局变量,c是局部变量,但都在属于函数内部不可见的外层变量。

cout<<"---MAIN---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
//---MAIN---
//i: 33 a: 0 b: -10 c: 8
//i仍然保持全局变量的好性质
//a,b,c退回使用main函数中的static变量。

i += 10; other();
//---OTHER---
//i: 75 a: 6 b: 4 c: 15
//i还是老样子,abc又是other函数中的变量
return 0;
}
原创文章 42 获赞 17 访问量 1527

猜你喜欢

转载自blog.csdn.net/weixin_45502929/article/details/105255827
今日推荐