C++中static关键字的两种用法

本文详细解释了C++中static关键字在类和结构体内外的使用,包括静态变量的链接特性、类内共享内存、初始化静态成员变量以及静态函数的访问规则。
摘要由CSDN通过智能技术生成

 C++中的static关键字不仅可以在类或者结构体外使用,而且也可以在类或者结构体内使用

一、在类或者结构体外使用static关键字

类外面的static,意味着你声明为static的符号,链接将只是在内部,这意味着它只能对你定义它的翻译单元可见。

静态变量或者函数意味着,当需要将这些函数或变量与实际定义的符号链接时,链接器不会在这个翻译单元的作用域之外寻找那个符号定义

加入static有点像在类中声明一个私有变量,其他所有的翻译单元都不能看到这个静态变量,链接器在全局作用域下,将不会看到这个变量

为什莫需要全局变量?

如果你不需要变量是全局变量,你需要尽可能的多使用静态变量,因为你一旦在全局作用域下申明东西的时候,如果没有设定static,那么链接器会跨编译单元进行链接

主函数:main.cpp 

#include <iostream>
using namespace std;


//extern int s_Variable; 
//extern意味着它会在外部翻译单元中寻找s_Variable变量,称为external linkage或者external linking

void Function()
{

}

int main()
{
	//cout << s_Variable << endl;
	cin.get();
	return 0;
}

static.cpp

static int s_Variable = 5; // 意味着这个变量只会在这个翻译单元内部链接
//静态变量或者函数意味着,当需要将这些函数或变量与实际定义的符号链接时,链接器不会在这个翻译单元的作用域之外寻找那个符号定义
// 加入static有点像在类中声明一个私有变量,其他所有的翻译单元都不能看到这个s_Variable变量,链接器在全局作用域下,将不会看到这个变量
static void Function()
{

}

二、在类或者结构体内使用static关键字

类或者结构体内部的静态变量意味着该变量实际上将与类的所有实例共享内存,这意味着该静态变量在你在类中创建的所有实例中,静态变量只有一个实例
同样适用于类中的静态方法,在类中,没有实例会传递给该方法

静态在一个类中意味着特定的东西,如果把它和变量一起使用,意味着在类的所有实例中,这个变量只有一个实例
即如果创建一个名为Entity的类,不断的创建Entity实例,仍然会得到那个变量的一个版本,意味着如果某个实例改变了这个静态变量,它会在所有实例中反应这个变化
通过类实例来引用静态变量是没有意义的,这就像类的全局实例,静态方法也一样,无法访问类的实例。静态方法可以被调用,不需要通过类的实例。而在静态方法内部,不能写引用到类实例的代码

为什莫静态成员变量需要在结构体外部进行初始化?

因为静态成员变量是属于类而不是属于类的实例。
在类的定义中只是声明了静态成员变量的存在,但是并没有为他们分配内存空间。因此需要在类的外部进行初始化来为静态成员变量分配内存空间并赋初值

为什莫在类中使用静态呢?

答案是将它们放在Entity中是有意义的,如果你有东西,比如一条信息,你想要在所有Entity实例之间共享数据或者将它实际存储在Entity类中是有意义的,因为它与Entity有关
要组织好的代码,那最好是在这个类中创建一个静态变量,而不是一些静态的或全局的东西到处乱放
静态方法的工作方式与此类似

int Entity::x;
int Entity::y;
“::”是作用域解析运算符,用于指定静态成员变量或者静态成员函数所属的类或者命名空间。
在这个例子中,Entity::x表示x是Entity类的静态成员变量,通过使用作用域解析运算符,可以访问或初始化类的静态成员函数
# include <iostream>
using namespace std;

struct Entity
{
	int x, y;
    加上static后,x,y不再是类成员,因此可以被所有的Entity的实例共享
	static int x, y;
    
	静态函数在类内部
    static void print(Entity e)
	{
		cout << e.x << ", " << e.y << endl;
	}

};

void print() 加上static后,能够正常工作,因为你可以看到它指向的x和y
如果决定让x和y是非静态的,print函数保持静态,但是静态方法不能访问非静态变量,原因是静态方法没有类实例,它不知道您想要访问哪个Entity的x和y,因为没有给他一个Entity的引用
对静态的东西能访问什么非静态的东西感到困惑?
本质上,类中的每一个方法,每个非静态方法总是获得当前类的一个实例作为参数,这是类在幕后的实际工作方式,它们通过隐藏参数发挥作用,静态方法不会得到那个隐藏参数,静态方法与在类外部编写方法相同

静态函数在类外部的写法:

static void print(Entity e) 本质上是非静态类方法在编译时的真实样子,将Entity e去掉正是我们将static关键字添加到类方法时所做的
{
	cout << e.x << ", " << e.y << endl;
}
static void print()
{
	cout << x << ", " << y << endl; // 不知带x和y是什么
}

int Entity::x;
int Entity::y;
“::”是作用域解析运算符,用于指定静态成员变量或者静态成员函数所属的类或者命名空间。
在这个例子中,Entity::x表示x是Entity类的静态成员变量,通过使用作用域解析运算符,可以访问或初始化类的静态成员函数
int main()
{
	Entity e;
	/*Entity::x = 2;
	Entity::y = 3;*/
	e.x = 2;
	e.y = 3;

	Entity e1;
	/*Entity::x = 5;
	Entity::y = 8;*/
	e.x = 5;
	e.y = 8;
    Entity::print(e);
	//Entity::print();
    加上static后,两个不同的Entity实例,他们的x和y指向同一个地方,他们指向相同的x和y
	cin.get();
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值