马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
类外
静态变量或函数意味着,当须要将这些变量或函数与实际界说的符号链接时,链接器不会在这个翻译单位的作用域之外探求谁人符号界说,即只会在这个翻译单位内部链接(文件内可用)
假如这句话并不明白,可以看一下【C++】How the C++ Compiler Works和【C++】How the C++ Linker Works
示例:
Main.cpp
- #include<iostream>
- int s_Variable = 10;
- int main() {
- std::cout << s_Variable << std::endl;
- }
复制代码 Static.cpp
- static int s_Variable = 5;
复制代码 没有标题,输出10
当删掉static int s_Variable = 5;
中的static后,报错了
我们可以将int s_Variable = 10;改为extern int s_Variable;
没有标题,输出5
函数也是类似的,动手试一试吧
类内
静态成员:指的是在C++类中声明成员时,可以加上static关键字,如许声明的成员叫静态成员。静态成员分为静态数据成员和静态函数成员两种。
静态数据成员界说
- class node{
- public:
- static int id;//静态数据成员定义
- };
- int node::id=10;//静态数据成员类外初始化
复制代码 静态数据成员的特点
- 类中的静态数据成员,全部对象都共享该数据,只有一份内存在内存中
- 类中的静态数据成员,必须要在类外初始化,由于它不属于对象,而是属于类。对象不管是否存在,这个静态数据成员都是存在的,而且静态数据成员的生命周期是步伐开始就存在(主函数运行之前),直到步伐竣事才会被开释
- 类中的静态数据成员,可以在类中被重新赋值,可以被平常函数访问,假如该成员是公有属性,那么还可以在类外被对象本身访问(没什么意义),大概通过类名访问
静态函数成员界说
- class node{
- public:
- static void fun(){}//在类中定义
- static void fun1();//在类中声明
- };
- void node::fun1(){}//在类外定义
复制代码 静态函数成员的特点
- 类中的静态函数成员,这个函数同样也不属于对象,而是属于类的,以是在这个函数中不能利用类中的平常数据成员清静凡成员函数。由于这些平常成员是必须要有对象的时间才会被创建,而静态函数不消对象也能调用
- 访问和静态数据成员划一
- 可以在这个静态函数中利用局部变量、形参、静态数据成员
示例:
- #include<iostream>
- struct Entity {
- int x, y;
- void print() {
- std::cout << x << "," << y << std::endl;
- }
- };
- int main() {
- Entity e;
- e.x = 2;
- e.y = 3;
- Entity e1;
- e1.x = 5;
- e1.y = 8;
- e.print();//2,3
- e1.print();//5,8
- }
复制代码 将x和y变为静态的:static int x, y;
并在结构体下面界说静态变量:
- int Entity::x;
- int Entity::y;
复制代码 输出:
e1.x = 5;像如许引用没什么意义
可以像如许引用:Entity::x = 5;
同样地,将print函数改为静态的
e.print();可以写成Entity::print();
也就是说我们没有须要实例化对象就能利用静态变量和方法
那么,上面的代码可以改为
- #include<iostream>struct Entity { static int x, y; static void print() { std::cout << x << "," << y << std::endl; }};int Entity::x;
- int Entity::y;
- int main() { Entity::x = 6; Entity::y = 7; Entity::print();}
复制代码 上面我们说它们属于类,是指它们是类中的一部分,实质上它们和在定名空间中一样
假如我们让方法保持静态,变量不为静态,改成下面如许:
- #include<iostream>
- struct Entity {
- int x, y;
- static void print() {
- std::cout << x << "," << y << std::endl;
- }
- };
- int main() {
- Entity e;
- e.x = 6;
- e.y = 7;
- Entity::print();
- }
复制代码 出现报错:对非静态成员“Entity::x”的非法引用
你不能从静态方法访问它,由于静态方法没有类实例
局部静态(Local Static)
静态局部变量答应我们声明一个变量,它的生命周期根本上相当于整个步伐的生命周期,但是它的作用域范围是被限定的。你可以在任何作用域中声明,假如在函数中声明,那么它的作用域范围被限定在这个函数中。
示例:
- #include<iostream>
- void Function() {
- static int i = 0;
- i++;
- std::cout << i << std::endl;
- }
- int main() {
- Function();
- Function();
- Function();
- Function();
- Function();
- }
复制代码 输出:
这意味着当我第一次调用函数时,这个变量将被初始化为0,然后全部对函数的后续调用实际上不会创建一个全新的变量
而下面这种情况就不会如许
- #include<iostream>
- void Function() {
- int i = 0;
- i++;
- std::cout << i << std::endl;
- }
- int main() {
- Function();
- Function();
- Function();
- Function();
- Function();
- }
复制代码 输出:
改变作用域范围也会到达同样的效果
- #include<iostream>
- int i = 0;
- void Function() {
- i++;
- std::cout << i << std::endl;
- }
- int main() {
- Function();
- Function();
- Function();
- Function();
- Function();
- }
复制代码 输出:
但这种方法的标题是我可以在恣意地方访问i
- Function();
- i=10;
- Function();
- Function();
- Function();
- Function();
复制代码 输出:
示例——单例类
- #include<iostream>
- class Singleton {
- private:
- static Singleton* s_Instance;
- public:
- static Singleton& Get() {
- return *s_Instance;
- }
- void Hello() {
- std::cout << "Hello" << std::endl;
- }
- };
- Singleton* Singleton::s_Instance = nullptr;
- int main() {
- Singleton::Get().Hello();
- }
复制代码 我们可以简化它
- #include<iostream>
- class Singleton {
- public:
- static Singleton& Get() {
- static Singleton instance;
- return instance;
- }
- void Hello() {
- std::cout << "Hello" << std::endl;
- }
- };
- int main() {
- Singleton::Get().Hello();
- }
复制代码 这里就是作为例子,并没有完全到达单例模式的效果,可以进一步相识:【C++】单例模式
static的五种用法
- 全局变量前加static修饰为文件作用域全局变量,内存在全局数据区
- 块作用域前加static修饰为块作用域变量,但内存在全局数据区
- 平常函数前加static修饰为文件作用域函数
- 类中数据成员前加static修饰为类中全部对象共享数据
- 类中函数成员前加static修饰为类中全部对象共享成员
|