C++ static详解

一.static的使用范围

1.static可以用来修饰对象(包括基本类型,用户自定义类型。普通对象,指针对象,引用对象)
2.static可以用来修饰函数

二.static修饰对象

2.1 static修饰不同地方定义的对象

2.1.1 静态全局变量
static int a = 1;//静态全局变量
int static b = 1;//静态全局变量
int c = 1;//全局变量
const int d = 1;//常量
const static int e = 1;//常量
static const int f = 1;//常量

定义静态全局变量的时候需要加上static不能加上const
静态全局变量的可见性是文件内,不能跨文件(在另一个文件想要调用需要使用全局变量)
静态全局变量的好处:访问性比较大,同一个文件的不同地方都可以使用。可以用于函数计数等

2.1.2 静态局部变量

这里说的静态局部变量通常是值定义在函数内的变量

int main()
{
	static int a = 1;//静态局部变量
	int static b = 1;//静态局部变量
	int c = 1;//栈中变量
	const int d = 1;//栈中变量
	const static int e = 1;//栈中常量
	static const int f = 1;//静态局部常量
}

在函数中定义的静态局部变量内存分布将会在静态全局区,而不在栈上,不会因为函数执行完毕而被清除。
静态局部变量的好处:访问性比静态全局变量小,但是可以也可以实现函数计数的功能,同时因为静态的原因,只会在程序初始化的时候分配一次内存

代码辨析:

#include<iostream>
using namespace std;
static int a = 1;
int static b = 1;
int c = 1;
const int d = 1;
const static int e = 1;
static const int f = 1;
void test()
{
	printf("\n");
	printf("%d",a);
	printf("%d",b);
	printf("%d",c);
}
int main()
{
	static int a = 2;
	int static b = 2;
	int c = 2;
	const int d = 2;
	const static int e = 2;
	static const int f = 2;
	printf("%d",a);
	printf("%d",b);
	printf("%d",c);
	printf("%d",d);
	printf("%d",e);
	a++;
	b++;
	c++;
	test();
	printf("\n");
	printf("%d",a);
	printf("%d",b);
	printf("%d",c);
} 

在这里插入图片描述

分析:我们发现,我们在定义了相同名称的静态全局变量和静态局部变量,我们访问他们的方式如下:
在本函数内查找,如果没有找到则会去函数外查找(不包括上一级函数,所有函数外!)

三.static修饰成员函数和成员变量

3.1 修饰成员变量
class A
{
	static int a;
	public:
		A()
		{
			a=0;
			//this.a=0;编译报错 
		}
};

分析:当我们将成员变量定义成static 它就不在只属于这个对象,而是被所有类对象共享(可以进行通信了!)。如果我们要进行
如果我们这么写

static int a = 0;///编译报错,forbids in-class initialization of non-const static member不能在类内初始化非const static成员

为什么我们不能在类中设定值呢?
C++标准只允许static constant intergral或者枚举类型的数据在类内进行初始化。
为什么标准不允许这一行为?
C++需要每一个对象有特定的定义。如果C++允许存储在内存中的对象进行类内定义,那么这一规则将会被打破。(C++不希望对象去定义类,而是由类的定义生成对象)
那我们怎样初始化呢?
1.将static 修改成 static const,这样编译器会为我们开一个后门,因为它不在会改变。
2.进行类外定义(如果是私有的怎么办,调用公共的static成员函数)

如何在类外定义呢?

class A
{
	public :
	static int a;
		A()
		{
			a=0;
			//this.a=0;编译报错 
		}
};
int A::a = 1; //类外定义,我们用  类型名称 类名称::变量名 = 值;去进行类外定义。
int main()
{
	
} 
3.2 static修饰成员函数

首先static修饰成员函数的时候还是有一些限制
不能修饰构造函数
不能修饰析构函数
不能修饰拷贝构造函数
不能修饰操作符重载函数(static可以修饰非成员函数的操作符重载,static几乎没用)
不能修饰虚函数
不能修饰纯虚函数

关于静态成员函数的继承问题(静态函数是可以被继承的)
静态成员函数只能访问静态成员变量不能访问其他成员变量

四.关于static 的一些特殊情况

union中可以定义静态函数,但是union中不能定义静态成员变量所以几乎没什么用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值