当前位置:首页 > 大杂烩 > 正文内容

c++存储类,c++auto关键字,c++ register关键字,c++static关键字,c++mutable关键字,c++thread_local关键字

高老师5年前 (2020-03-20)大杂烩1495

(1).储存类是干嘛的?第一次听起来以为是面向对象相关的知识,其实不是.它主要用来定义变量或函数的范围,可见性,生命周期。

(2).储存类主要有哪些?

auto (C++17开始被废弃)

register(C++17开始被废弃)

static

extern

mutable

thread_local

(3).auto储存类.声明的变量会自动推断该变量的类型(不需要关注它,毕竟官方已经开始废弃它了)

#include <iostream>
#include <typeinfo>
int main()
{
    auto  a = 3;
    auto  b = "b";
    auto  c = 3.14;
    auto  d = false;
    auto  e = new auto(1024);
    
    //输出a的类型:int
    std::cout << typeid(a).name() << std::endl;
    //输出b的类型:char const *
    std::cout << typeid(b).name() << std::endl;
    //输出c的类型:double
    std::cout << typeid(c).name() << std::endl;
    //输出c的类型:bool
    std::cout << typeid(d).name() << std::endl;
    //输出e的类型:int *
    std::cout << typeid(e).name() << std::endl;
   return 0;
}

可以看到auto储存类和php一样骚,自动类型推断。

(4).register官方解释:储存类用于定义储存在寄存器中而不是RAM中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个词),且不能对它应用一元的"&"运算符(因为它没有内存位置)

     register个人解释:register储存类创建的变量是存放在CPU的寄存器上面,这不同于普通变量在内存上面存放。寄存器中直接读写变量,可以提高效率。但是寄存器空间小,不应该重度依赖。

实例代码:

    register int a = 1;
    std::cout << a;

上面说不能对它使用"&"运算符我测试好像并不对,例如下面的代码进行位运算:

    register int a = 60;
    register int b = 13;
    int c = a & b;

    std::cout << c;

(5).static储存类指示编译器在程序的生命周期内保持局部变量的存在,使用static修饰局部变量可以在函数调用之间保持局部变量的值。还是直接上代码吧:

#include <iostream>
#include <typeinfo>
using namespace std;

//函数声明
void func();

//static修饰全局变量
static int all_count = 10;

int main()
{
	//全局变量递减
	while (all_count--)
	{
		func();
	}

	return 0;
}

void func()
{
	//static修饰局部变量
	static int a = 0;

	//局部变量递增
	a++;

	std::cout << "全局变量all_count的值为:" <<  all_count << std::endl;
	std::cout << "局部变量a的值为:" << a << std::endl;
}

首先看修饰全局变量,我去除全局变量的修饰,发现执行结果是一致的。那是不是static修饰全局变量没有意义呢?不是的,static修饰全局变量限制了它的作用域只能在当前的源文件中,避免其他文件使用这个全局变量,其他文件还能命名相同名字的全局变量,不会发生命名冲突。

再看修饰局部变量,假如没有修饰局部变量,那么每次输出的局部变量的值都是1,但是增加了static修饰符,局部变量会记住上次的值,这样值就一直在累计,但是并不能改变它的作用域,它的作用域还是局部的。

(6).extern储存类请参考前面的文章https://blog.20230611.cn/?id=304

(7).mutable储存类暂时未学到面向对象,后面补全

(8).thread_local储存类修饰的变量具有线程周期,什么是线程周期,就是说变量或者对象在线程开始的时候被生成,在线程结束的时候被销毁。

先看代码:

#include <iostream>
#include <thread>
using namespace std;

//创建thread_local修饰的全局变量
thread_local int a = 1;

//定义方法f
void f()
{
	a++;
	printf("id:%d,a:%d\r\n", std::this_thread::get_id(), a);
}

int main()
{
	//全局变量自增
	a++;

	//执行f方法
	f();

	//创建线程t1和t2,并设置执行方法为f
	std::thread t1(f);
	std::thread t2(f);
	t1.join();
	t2.join();

	return 0;
}

我们发现虽然在主进程/线程中变量a的值已经被修改为3了,并且变量a是全局变量,但是在子进程中变量a的初始化的值都是1。原因就是thread_local修饰符,子进程启动时会复制它的原始值,当然你可以把修饰符去掉再测试。

输出结果为:

id:14532,a:3
id:14252,a:2
id:14152,a:2

我们发现虽然在主进程/线程中变量a的值已经被修改为3了,并且变量a是全局变量,但是在子进程中变量a的初始化的值都是1。原因就是thread_local修饰符,子进程启动时会复制它的原始值,当然你可以把修饰符去掉再测试。

扫描二维码推送至手机访问。

版权声明:本文由高久峰个人博客发布,如需转载请注明出处。

本文链接:https://blog.20230611.cn/post/549.html

分享给朋友:

“c++存储类,c++auto关键字,c++ register关键字,c++static关键字,c++mutable关键字,c++thread_local关键字” 的相关文章

c#中string和StringBuilder效率对比

c#中string和StringBuilder效率对比

    c#中string和StringBuilder直接看看执行速度。(2).String类型累计赋值Test               ...

svn自动更新到网站

svn自动更新到网站

【一】.钩子文件的设置和创建(1).打开hooks目录,可以看到有一个post-commit.tmpl文件,这是一个模板文件。复制一份,重命名为post-commit,将其用户组设为www,并设置为可执行。chown www:www post-commitchmod +x post-commit(2...

Git本地仓库学习

Git本地仓库学习

1.全局用户信息设置 git  config  --global  user.name  gaojiufeng git  config  --global  user.email  392223903...

Git推送文件到远程仓库

Git推送文件到远程仓库

1.远程仓库的协作模式开发者把自己最新的版本推到线上仓库,同时把线上仓库的最新代码,拉到自己本地即可2.注册git帐号国外: http://www.github.com国内: http://git.oschina.net2.在码云创建项目,不要初始化readmegit push https://gi...

Git日志查看和版本切换

Git日志查看和版本切换

日志查看:git log版本切换:方式1:git  reset  --hard  HEAD^   倒退一个版本git  reset  --hard  HEAD^^  倒退两个版本方式2:(版本号的形式,建议版本号码补充完...

c#关闭计算机的代码

c#关闭计算机的代码

    1.关机Process.Start("shutdown", "-s -t 0");    2. 注销  Proc...