什么是 C++ 局部静态?使用局部静态生成 UUID

开场

首先上场的是一段平平无奇的代码

#include <stdio.h>

int count = 0;

int generate_uuid()
{
	return count++;
}

int main()
{
	for (int i = 0; i < 3; i++)
	{
		printf("%d ", generate_uuid());
	}
	
	return 0;
}

太简单了!我的肉脑编译器在瞬间就得出了输出结果:0 1 2

哦?那如果我把 count++ 换成 ++count 呢?

int generate_uuid()
{
	return ++count;
}

小样!这个我知道!count++ 是先返回 count 再 +1,++count 是先 +1 再返回 count,所以输出结果是:1 2 3

这就是这篇文章的内容了嘛,语言顶针,鉴定为挂羊头卖狗肉,举办了

不!不要!再来看下面这段代码!

刚才的 count 变量是一个全局变量,不够优雅,这是升级的版本!

#include <stdio.h>

class UUID
{
public:
	static int generate()
	{
		return count++;
	}
	
private:
	static int count;
};

int UUID::count = 0;

int main()
{
	for (int i = 0; i < 3; i++)
	{
		printf("%d ", UUID::generate());
	}
	
	return 0;
}

就这?你以为套个面向对象的壳就能难倒我了?C++ 学习时长两年半!这段代码的输出结果是:0 1 2

所以,这和今天的主题有什么关系嘛,我真要举办了

既然如此,请看!这是最后的代码!

#include <stdio.h>

int generate_uuid()
{
	int count = 0;
	
	return count++;
}

int main()
{
	for (int i = 0; i < 3; i++)
	{
		printf("%d ", generate_uuid());
	}
	
	return 0;
}

这段代码的输出结果是:0 0 0

所以我怀疑你在耍我,这就是最后的代码?就这?就这!

哦抱歉,拿错代码了,真正的!最后的!代码在这!

#include <stdio.h>

int generate_uuid()
{
	static int count = 0;
	
	return count++;
}

int main()
{
	for (int i = 0; i < 3; i++)
	{
		printf("%d ", generate_uuid());
	}
	
	return 0;
}

哦?有点意思,你成功引起了我的注意,码农。给我讲讲看,这是什么

哈哈!这段代码的运行结果是:0 1 2

局部静态

最后一份代码较之上一份代码,不同之处在于 generate_uuid 函数中的 count 变量前多了一个 static 修饰符,有什么作用呢?

众所周知,static 被称作静态修饰符,最常见的应用场景便是用在类中,将类的成员提升到类的层面,这会让所有的类对象都只能访问同一个静态成员,而不是每个对象都各自持有一个

这个最常见的用法容易让人产生一种想法,那就是 static 可以将类成员提升到类层面。嗯,废话。

重点是,为什么呢?

内存分区中有一个区域叫做全局静态区,专门用来存储全局变量和静态变量,其中的静态变量即指被 static 修饰符修饰过的变量

全局静态区存储的变量在相同作用域内是全局唯一的

回到刚才的问题,为什么 static 可以将类成员提升到类层面呢?因为被 static 修饰的成员被存储到了全局静态区,变成了全局唯一的变量,所以所有类的对象当然只能访问同一个静态变量

但是,既然是全局唯一的,为什么这个类定义的只能这个类访问,其他类不能访问呢,这不扯犊子嘛

注意,还有一个关键词,叫相同作用域,当定义一个类时,类的作用域就是定义类使用到的 { } 花括号内部,你在这里面使用 static 修饰的变量即表示:作用域为该类的静态变量

什么是作用域,也就是只在该作用域内起作用,在其他地方可不许访问,所以只有当处在同一个作用域内时,才可访问该作用域的静态变量

回到一开始的例子,generate_uuid 函数中,使用 static 修饰的 count 变量被存储到了全局静态区,变成了静态变量,但是!count 的作用域只在 generate_uuid 函数中,所以外部是无法访问的,而处在同一作用域的 return 语句当然可以狠狠地访问它,还对它进行了 +1 操作

而函数的作用域,很显然是定义这个函数所使用到的 { } 内部

核心便是作用域这个概念

最后,值得一提的是,当在函数内使用局部静态变量时,静态变量会在函数第一次被调用时进行定义,而之后函数再被调用时,将不会再重新定义静态变量,而是访问那个在第一次调用时就被创建的静态变量

真棒!我又懂了!(逃)

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值