c++学习笔记十三——数据作用域以及生存期

数据作用域就是一个数据有效的区域
数据作用域数据有效的区域,数据作用域包括以下几种
函数作用域:
说简单一些就是函数的形参,函数在声明中 作用域只限于括号范围内,如有以下代码

void show(int x);

其中在声明中x的作用域仅限于括号内,由于编译器只检查参数类型,而不检查参数的名称,所以可以在声明中不定义名称,但是为了读起来方便理解最好还是定义名字。
局部作用域:
函数形参列表中的定义域,从函数形参开始一直到函数体结束,函数体内声明的变量,其作用域从声明开始,一直到声明所在块结束的大括号为止,其中所谓块,就是一对大括号括起来的一段程序。具体示意图如下图所示:

我们可以从图中看到各个函数的作用域。
类作用域:
类可以被看成一组有名成员的集合,若类中成员为public属性,那么可以使用
对象名.成员名来访问类中的数据成员,也可以通过 ptr->成员名来访问,其中ptr为指向类的指针。或者可以通过类名::对象进行访问,总结一下就是通过两种方式进行访问,X.y或者 X::y。
命名空间作用域:
命名空间的作用为防止同名产生的歧义,因为程序有很多模块构成,其中每个模块的名字很有可能重名,这样就可能造成歧义,所以我们采用命名空间的方式防止名字相同而产生的歧义。我们在C++j经常见到一句话
using namespace std;这句话的意思就是使用了std的命名空间,若不加上这句话,我们在使用函数时需要在前面加上 std::
以上介绍了三个数据的作用域,分别为函数作用域,局部作用域,以及类作用域,命名空间作用域,下面介绍**标识符的可见性,**首先观察如下图
标识符作用域
标识符可见性的规则是,如果内层空间与外层空间没有相同的变量名,则在内部空间可以访问外部空间的变量,但如果内部空间与外部空间有相同的变量名,则屏蔽外部空间变量,这些规则可能有些绕口那么下面让我来举一个例子说明空间作用域的关系。
具体举例子代码如下

# include <iostream>
namespace global {
    
    
	int i; //在命名空间global 中定义全局变量 i
}
int j;   //定义全局变量j
int main()
{
    
    
global::i = 2;//将全局变量=2
j = 3;

//块作用域
{
    
      

	//定义与全局作用域相同名字的变量测试是否会屏蔽
	int i = 4;
	std::cout << "i =" << i << std::endl;
	//输出j变量
	std::cout << "j =" << j << std::endl;


}
}

运行的结果如下;
作用域域可见性
(注意具有命名空间变量拥有全局作用域)

下面介绍数据的生存期
静态生存期
对象的生存周期与程序运行期相同,称它具有静态生存期,若在函数的内部想要声明具有静态生存期的对象我们需要使用关键字 static,在声明具有静态生存期的对象以后,该对象不会建立副本,也不会随着函数的返回而失效,也就是说当函数返回该对象时,在继续调用下一次的值的时候该值依然会保存该值。
动态生存期
该对象诞生于声明点,结束于所在块执行完毕之时。
下面举一个静态函数成员的例子
建立一个类,每当调用构造函数与复制函数时就进行计数

# include<iostream>
using namespace std;
class point
{
    
    
private:
	int x;
	int y;//非静态成员
	static int count;//静态数据成员的声明在类内,定义以及初始化要放在类外
public:
	point(int x, int y) :x(x), y(y) {
    
     cout << "calling construction " << endl; count++; }
	int getx() {
    
     return x; }
	int gety() {
    
     return y; }
	void show() {
    
     cout << "count is  " << count << endl; }
	//static  void show() { cout << "count is  " << count << endl; }
	point(point &s) {
    
    
		x = s.x;
		y = s.y;
		count++;
	}
	~point() {
    
     count--; }
};
int point::count = 0;//类外初始化定义
int main()
{
    
    
	point a(1, 2);
	a.show();
	point b(a);
	b.show();//count =2,因为前面已经构造了a,所以count=2



}

运行结果如下
在这里插入图片描述
这个可以看到因为静态数据成员生存周期与程序运行的时间相同,因此输出第二个count 时会为2。那么就有一个问题出现了,当一个类都没有,查看当前的count值,本应该是0,但是count是私有成员,所以只能通过对象名.成员名访问,一旦定义对象,则count++,所以无法直接查看。可以采用静态函数解决。
静态函数 对于非静态函数,则知道哪个对象调用了它,但是静态成员函数不知道是哪个对象调用,所以可以处理静态函数成员

感兴趣的读者可以尝试试试看。调用非静态函数处理相关问题。

猜你喜欢

转载自blog.csdn.net/qq_41803340/article/details/112724468