当前位置:   article > 正文

c++ static_c++全局静态变量是线程安全的吗

c++全局静态变量是线程安全的吗

(1)修饰局部变量 


一般情况下,对于局部变量是存放在栈区的,并且局部变量的生命周期在该语句块执行结束时便结束了。但是如果用static进行修饰的话,该变量便存放在静态数据区,其生命周期一直持续到整个程序执行结束。但是在这里要注意的是,虽然用static对局部变量进行修饰过后,其生命周期以及存储空间发生了变化,但是其作用域并没有改变,其仍然是一个局部变量,作用域仅限于该语句块。 

静态局部变量初始化的线程安全

C++11 保证静态局部变量的初始化过程是线程安全的。

这里的线程安全指的是:一个线程在初始化 m 的时候,其他线程执行到 m 的初始化这一行的时候,就会挂起。

(2)修饰全局变量 


对于一个全局变量,它既可以在本源文件中被访问到,也可以在同一个工程的其它源文件中被访问(只需用extern进行声明即可)。用static对全局变量进行修饰改变了其作用域的范围,由原来的整个工程可见变为本源文件可见。 

源文件中static修饰的全局变量和函数只能在本源文件使用。

前提条件是static一定要在源文件中修饰。

注意,源文件是什么文件,头文件是什么文件。

头文件中加static不影响这个变量在其源文件中的作用域。

  1. /main.cpp
  2. #include "function.h"
  3. int main() {
  4. cout << veri << endl;
  5. //func();
  6. return 0;
  7. }
  8. //function.h
  9. #pragma once
  10. #include <iostream>
  11. using namespace std;
  12. extern int veri;
  13. void func();
  14. //function.cpp
  15. #include "function.h"
  16. static int veri = 123;
  17. static void func() {
  18. cout << "static func" << endl;
  19. }

上面的程序运行会报错,因为veri只能在.cpp文件中访问。

在源文件中的非static修饰的全局变量和函数能不能在其他文件中用extern声明

用于声明一个全局变量或函数:当我们在源文件中定义一个全局变量或函数时,其作用域仅限于该文件中。如果需要在其他文件中访问该变量或函数,就需要使用extern关键字进行声明。例如,在一个.cpp文件中定义了一个全局变量int a,如果需要在另一个.cpp文件中使用该变量,就需要在该文件中使用extern int a进行声明,这样编译器就知道了a变量存在于其他文件中。


(3)修饰函数 


用static修饰函数的话,情况与修饰全局变量大同小异,就是改变了函数的作用域。 


(4)static在类中的运用


首先要明白类的对象在建立时发生了什么:
类的对象在建立时进行了类的数据成员的拷贝,每一个对象都有自己的数据成员,但是并不是拷贝类的所有数据,成员函数,静态成员函数和静态成员变量就是**共享的,不拷贝的**。
被static修饰的类的数据成员(函数和变量),表明该数据成员对该类所有对象都只有一个实例。即该数据成员归所有对象共同享用。

静态成员函数


1:类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致 了它仅能访问类的静态数据和静态成员函数。
2:不能将静态成员函数定义为虚函数。    
3:如何在类的静态函数中访问类的动态成员:
将类对象作为参数传递给类的静态成员函数,就可以通过这个对象访问类的任何成员。(比如,将对象的this指针传递给类的静态成员)

类静态成员的调用

可以通过类的对象,引用和指针来访问类的静态成员,也可以直接用类名和作用域运算符来访问静态成员

person::allPerson();
//p2.display();

静态成员变量

3:静态成员初始化与一般数据成员初始化不同:
**初始化在类外进行,而前面不加static。
如果要在类内初始化,要为静态成员变量提供const或者constexpr修饰,并且初始值必须是常量表达式。(静态成员函数不能声明为const)**
初始化时不加该成员的访问权限控制符private,public等;
4:默认初始化为0:在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量(  全局变量也具备这一属性,因为全局变量也存储在静态数据区  )
5:可以通过类的对象,引用和指针来访问类的静态成员

全局的static和局部的static有什么区别

1,作用域不同

c的static和c++有什么区别

1,因为C++兼容C语言,所以C中的static具有的特性,在C++中同样适用。

只是c++是面向对象的语言,所以c++多了静态成员函数和静态成员变量的用法。

2,对静态变量的初始化时间段不同。

静态变量初始化

C中局部静态变量和全局变量的内存分配和初始化都是在编译阶段

(这就是C中无法使用变量初始化静态变量的原因)

C++中全局变量和类的静态成员变量在编译时分配内存并初始化,局部静态变量只有在第一次使用的时候才会进行内存分配和初始化,全局对象和静态局部对象也是只有在第一次使用的时候才会进行内存分配和初始化。

类的静态变量

必须在类外初始化(因为不属于类对象,共享)

如果想在类内初始化怎么办:

设置为静态常量:static const int a=10;

类的静态变量为什么一定要初始化

因为类内知识声明,未定义

详细连接

static修饰的变量的唯一性

无论是静态类成员变量还是普通静态成员变量,static修饰,则编译期就分配内存了,在整个程序中尽管多次获取还是同一个变量。

static返回静态局部对象和静态局部变量

返回静态局部对象

  1. #include <iostream>
  2. class test{
  3. public:
  4. static test get(){
  5. static test t;
  6. return t;
  7. }
  8. int a{0};
  9. };
  10. int main(){
  11. test tt=test::get();
  12. tt.a=100;
  13. std::cout<<"t1.a="<<tt.a<<std::endl;
  14. test t2=test::get();
  15. std::cout<<"t2.a="<<tt.a<<std::endl;
  16. return 0;
  17. }

返回的是对象本身。

返回静态局部变量

  1. #include <iostream>
  2. int get(){
  3. static int a=100;
  4. return a;
  5. }
  6. int main(){
  7. int b=get();
  8. b++;
  9. std::cout<<"b="<<b<<std::endl;
  10. int c=get();
  11. std::cout<<"c="<<c<<std::endl;
  12. return 0;
  13. }

为什么静态局部变量返回的是变量的值,而类的静态局部对象返回的是对象本身?

本质上都是返回值。

静态局部对象返回值和引用的区别

  1. class test{
  2. public:
  3. static test get(){
  4. static test t;
  5. return t;
  6. }
  7. static test& get(){
  8. static test t;
  9. return t;
  10. }
  11. int a{0};
  12. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/336481
推荐阅读
  

闽ICP备14008679号