【C++】static(静态)

[复制链接]
发表于 2025-12-24 23:41:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
类外

静态变量或函数意味着,当须要将这些变量或函数与实际界说的符号链接时,链接器不会在这个翻译单位的作用域之外探求谁人符号界说,即只会在这个翻译单位内部链接(文件内可用)
假如这句话并不明白,可以看一下【C++】How the C++ Compiler Works和【C++】How the C++ Linker Works
示例:
Main.cpp
  1. #include<iostream>
  2. int s_Variable = 10;
  3. int main() {
  4.         std::cout << s_Variable << std::endl;
  5. }
复制代码
Static.cpp
  1. static int s_Variable = 5;
复制代码
没有标题,输出10
当删掉static int s_Variable = 5;
中的static后,报错了
我们可以将int s_Variable = 10;改为extern int s_Variable;
没有标题,输出5
函数也是类似的,动手试一试吧
类内

静态成员:指的是在C++类中声明成员时,可以加上static关键字,如许声明的成员叫静态成员。静态成员分为静态数据成员和静态函数成员两种。
静态数据成员界说
  1. class node{
  2.     public:
  3.             static int id;//静态数据成员定义
  4. };
  5. int node::id=10;//静态数据成员类外初始化
复制代码
静态数据成员的特点

  • 类中的静态数据成员,全部对象都共享该数据,只有一份内存在内存中
  • 类中的静态数据成员,必须要在类外初始化,由于它不属于对象,而是属于类。对象不管是否存在,这个静态数据成员都是存在的,而且静态数据成员的生命周期是步伐开始就存在(主函数运行之前),直到步伐竣事才会被开释
  • 类中的静态数据成员,可以在类中被重新赋值,可以被平常函数访问,假如该成员是公有属性,那么还可以在类外被对象本身访问(没什么意义),大概通过类名访问
静态函数成员界说
  1. class node{
  2.     public:
  3.             static void fun(){}//在类中定义
  4.             static void fun1();//在类中声明
  5. };
  6. void node::fun1(){}//在类外定义
复制代码
静态函数成员的特点

  • 类中的静态函数成员,这个函数同样也不属于对象,而是属于类的,以是在这个函数中不能利用类中的平常数据成员清静凡成员函数。由于这些平常成员是必须要有对象的时间才会被创建,而静态函数不消对象也能调用
  • 访问和静态数据成员划一
  • 可以在这个静态函数中利用局部变量、形参、静态数据成员
示例:
  1. #include<iostream>
  2. struct Entity {
  3.         int x, y;
  4.         void print() {
  5.                 std::cout << x << "," << y << std::endl;
  6.         }
  7. };
  8. int main() {
  9.         Entity e;
  10.         e.x = 2;
  11.         e.y = 3;
  12.         Entity e1;
  13.         e1.x = 5;
  14.         e1.y = 8;
  15.         e.print();//2,3
  16.         e1.print();//5,8
  17. }
复制代码
将x和y变为静态的:static int x, y;
并在结构体下面界说静态变量:
  1. int Entity::x;
  2. int Entity::y;
复制代码
输出:
  1. 5,8
  2. 5,8
复制代码
e1.x = 5;像如许引用没什么意义
可以像如许引用:Entity::x = 5;
同样地,将print函数改为静态的
e.print();可以写成Entity::print();
也就是说我们没有须要实例化对象就能利用静态变量和方法
那么,上面的代码可以改为
  1. #include<iostream>struct Entity {        static int x, y;        static void print() {                std::cout << x << "," << y << std::endl;        }};int Entity::x;
  2. int Entity::y;
  3. int main() {        Entity::x = 6;        Entity::y = 7;        Entity::print();}
复制代码
上面我们说它们属于类,是指它们是类中的一部分,实质上它们和在定名空间中一样
假如我们让方法保持静态,变量不为静态,改成下面如许:
  1. #include<iostream>
  2. struct Entity {
  3.         int x, y;
  4.         static void print() {
  5.                 std::cout << x << "," << y << std::endl;
  6.         }
  7. };
  8. int main() {
  9.         Entity e;
  10.         e.x = 6;
  11.         e.y = 7;
  12.         Entity::print();
  13. }
复制代码
出现报错:对非静态成员“Entity::x”的非法引用
你不能从静态方法访问它,由于静态方法没有类实例
局部静态(Local Static)

静态局部变量答应我们声明一个变量,它的生命周期根本上相当于整个步伐的生命周期,但是它的作用域范围是被限定的。你可以在任何作用域中声明,假如在函数中声明,那么它的作用域范围被限定在这个函数中。
示例:
  1. #include<iostream>
  2. void Function() {
  3.         static int i = 0;
  4.         i++;
  5.         std::cout << i << std::endl;
  6. }
  7. int main() {
  8.         Function();
  9.         Function();
  10.         Function();
  11.         Function();
  12.         Function();
  13. }
复制代码
输出:
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
复制代码
这意味着当我第一次调用函数时,这个变量将被初始化为0,然后全部对函数的后续调用实际上不会创建一个全新的变量
而下面这种情况就不会如许
  1. #include<iostream>
  2. void Function() {
  3.         int i = 0;
  4.         i++;
  5.         std::cout << i << std::endl;
  6. }
  7. int main() {
  8.         Function();
  9.         Function();
  10.         Function();
  11.         Function();
  12.         Function();
  13. }
复制代码
输出:
  1. 1
  2. 1
  3. 1
  4. 1
  5. 1
复制代码
改变作用域范围也会到达同样的效果
  1. #include<iostream>
  2. int i = 0;
  3. void Function() {
  4.         i++;
  5.         std::cout << i << std::endl;
  6. }
  7. int main() {
  8.         Function();
  9.         Function();
  10.         Function();
  11.         Function();
  12.         Function();
  13. }
复制代码
输出:
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
复制代码
但这种方法的标题是我可以在恣意地方访问i
  1.         Function();
  2.         i=10;
  3.         Function();
  4.         Function();
  5.         Function();
  6.         Function();
复制代码
输出:
  1. 1
  2. 11
  3. 12
  4. 13
  5. 14
复制代码
示例——单例类
  1. #include<iostream>
  2. class Singleton {
  3. private:
  4.         static Singleton* s_Instance;
  5. public:
  6.         static Singleton& Get() {
  7.                 return *s_Instance;
  8.         }
  9.         void Hello() {
  10.                 std::cout << "Hello" << std::endl;
  11.         }
  12. };
  13. Singleton* Singleton::s_Instance = nullptr;
  14. int main() {
  15.         Singleton::Get().Hello();
  16. }
复制代码
我们可以简化它
  1. #include<iostream>
  2. class Singleton {
  3. public:
  4.         static Singleton& Get() {
  5.                 static Singleton instance;
  6.                 return instance;
  7.         }
  8.         void Hello() {
  9.                 std::cout << "Hello" << std::endl;
  10.         }
  11. };
  12. int main() {
  13.         Singleton::Get().Hello();
  14. }
复制代码
这里就是作为例子,并没有完全到达单例模式的效果,可以进一步相识:【C++】单例模式

static的五种用法

  • 全局变量前加static修饰为文件作用域全局变量,内存在全局数据区
  • 块作用域前加static修饰为块作用域变量,但内存在全局数据区
  • 平常函数前加static修饰为文件作用域函数
  • 类中数据成员前加static修饰为类中全部对象共享数据
  • 类中函数成员前加static修饰为类中全部对象共享成员
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表