C++中的static

C++中的static

c++中使用static关键字根据不同位置有几种情况:

  • 在类或者结构体外面
  • 在类或者结构体里面
  • 局部的static

在类或者结构体外面

类外的static修饰在link阶段是局部的,它仅对定义它的编译单元可见。而在类或者结构体内部定义表示这部分内存是这个类所有实例共享的。

全局变量默认具有外部链接性,在整个工程可见。使用static关键字可以限制全局变量的作用域,全局静态变量的作用域仅限编译单元内,它对在编译单元不可见

例如,如果你在一个单元里定义了一个extern int value;,它会在别的编译单元里去找定义,但是没办法找到别的编译单元里类外的static的定义。

1
2
3
4
5
6
7
8
9
10
# Main.cpp
#include <iostream>

extern int value;

int main() {
std::cout <<"print test"<< test << std::endl;
system("pause");
return 0;
}
1
2
# People.cpp
static int value = 22;

编译会报错:

1
2
LNK2001	无法解析的外部符号 "int value" (?value@@3HA) 
LNK1120 1 个无法解析的外部命令

如果把static int value = 22;改成int value = 22;编译就可以通过。

所以,如果你在类外定义的static变量或者static 函数,它只对其声明所在的cpp文件可见。如果你在头文件中定义了静态变量,然后在多个cpp文件里include了该头文件,由于预处理会把这部分代码复制到对应的cpp中,所有这些编译单元都创建了这个static变量。

什么时候用static呢?

可以想想你什么时候会在class成员中用private,如果你不想变量是全局可见的,那基本上static用的越多越好。因为如果不带static关键字定义了全局变量的话,那所有编译单元里都会想着它,很容易出现各种bug。所以尽量让全局函数和变量static,除非必须要他们用在其他的编译单元里。

在类或者结构体里面

类或者结构体内部定义的static变量或者函数表示这部分内存是这个类所有实例共享的,不论这个类有多少个实例,他们访问的都是同一个变量。如果有一个实例改变了该变量的值,所有其他实例对该变量的引用都会受到影响。

static变量属于类变量,而非具体类实例的变量。static函数也是类函数,与不同类函数不同的是,它没有传入this指针,正因为没有this指针,所以static类成员函数不能访问非static的类成员,只能访问 static修饰的类成员。

什么时候在类内部使用static

需要一个数据对象为整个类而非某个具体对象服务,同时不希望破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

局部的static

实际上,我们也可以在一个局部环境里声明一个static变量,所谓局部的环境可以是一个函数体里面,在一个for循环或者其他什么的,总之在一个局部的{}中,这种做法,可以既保障该static变量不会在作用域以外被使用,又使得它只会被初始化一次。

在实际的编码过程中,我很少见到这种写法,用这种方式最常见的就是单例模式。

1
2
3
4
5
6
7
class Singleton {
public:
static Singleton& GetInstance{
static Singleton instance;
return instance;
}
};

C++这种单例方式使得代码变得更加简洁。



关注博客或微信搜索公众号多媒体与图形,获取更多内容,欢迎在公众号留言交流!
扫一扫关注公众号
作者

占航

发布于

2022-05-01

更新于

2023-10-04

许可协议

评论