【C++学习笔记 5】C++中的static

类中的static

在class之外的static,意味着被修饰的符号在link阶段只在局部有效,它只对定义它的编译单元(.obj)可见。
在class或struct中的static,这意味着这部分内存是这个类中的所有实例所共享的。

举个例子

#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 = {5, 8};
	e.Print();
	e1.Print();
	std::cin.get();
}

当运行时,我会获得”2,3“和”5,8“,毫无疑问。
当修改代码,将xy改为静态变量时,编译器直接报错。
为了消除报错,修改代码,并定义静态变量

#include <iostream>
struct Entity
{
	static int x, y;
	void Print()
	{
		std::cout << x << "," << y << std::endl;
	}
};
int Entity::x;
int Entity::y;
int main() 
{
	Entity e;
	e.x = 2;
	e.y = 3;
	Entity e1;
	e1.x = 5;
	e1.y = 8;
	e.Print();
	e1.Print();
	std::cin.get();
}

这时再运行,则会发现打印了两次”5,8“,表明在这两个实例指向的变量处在一个内存空间。
因此上述代码相当于

Entity::x = 5;
Entity::y = 8;

跟直接在类中定义并无区别,从这种意义上说,他们并不真的属于类。

静态方法不能访问非静态变量

值得一提的是,如果将Print()函数定义为静态,此时用其调用非静态的实例时则会报错。原因是静态方法没有类实例。本质上,在类中写的每个非静态方法都会获得当前的类实例作为参数。从本质上讲,静态方法与在类外定义的函数并无区别,这也是为何在调用非静态参数时会报错,它根本没有获取到实例中的参数。

局部作用域中的static

变量的生命周期与作用域
生命周期,即变量在内存中,被删除前存在的时间。
作用域,即我们能够访问这个变量的范围。比如在函数内部定义的变量就不能被外部访问,因为它是局部的。
静态局部变量(local static)则允许我们声明一个变量,它的生命周期是程序的存在时间,而作用域取决于其所在的位置,如函数内部。

举个例子

#include <iostream>
void Function()
{
	int i = 0;
	i++;
	std::cout << i << std::endl;
}
int main() 
{
	Function();
	Function();
	Function();
	Function();
	Function();
	std::cin.get();
}

比如说这段代码,i在函数内被声明,因此当我连续五次调用Function()时,控制台上会显示出5次1,但当我把变量类型改为static int,我则会获得自增的五个数字1~5。
那么问题来了,static int与在函数外直接声明i有什么区别呢?
区别在于上面提到的作用域,如果在外部声明了i,则可在代码的任何位置访问到它,这可能导致程序的运行错误,比如在第一次调用Function()后将将i赋值为10,则结果变为1以及11~15。


教程来源:The Cherno C++ 教程

  • 19
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值