Cherno C++笔记【21-23 static】

c++笔记

【21】静态(static)

C++ 中的 static 关键字的意思取决于上下文,在类或者结构体外部使用 static 关键字和内部使用是不一样的。在类外使用 static 这意味着该成员只在内部生效,意味着其作用域仅限于该 cpp 文件内,意味着只对该编译单元可见,链接器不会再该编译单元外寻找它的定义。
如果定义了一个static变量,那么在其他的cpp文件中,调用该变量,就会出现Link报错。
如果不加static,则表示为全局变量,在同一个项目中不能用两个名字相同的全局变量。

如果想Link到外部cpp文件的static变量,可以在本cpp文件中声明 extern int s _variable.这被称为 external linkage或external linking。

如果在头文件中声明一个static 变量,并将该头文件包含在不同的cpp文件中,就相当于在两个cpp文件中都声明了同一个static 变量。

全局变量是“不好”的,除非真的需要函数和变量跨翻译单元link,否则创建静态变量与函数。

【22】类和结构体中的静态

静态变量

静态成员变量是所有实例共享的,但是其只是在类中进行了声明,并未定义或初始化(分配内存),类或者类实例就无法访问静态成员变量,这显然是不对的,所以必须先在类外部定义,也就是分配内存。
在 C++ 中,类中的静态成员变量属于整个类共享,可以通过类名或类的实例来访问它们。

具体来说,使用类中的静态成员变量需要遵循以下格式:

在类中声明静态成员变量
在类中声明静态成员变量时,需要使用 static 关键字,并且不能进行初始化。例如:

class MyClass {
public:
    static int x;    // 声明静态成员变量 x
};

在类外部定义和初始化静态成员变量
在类外部定义和初始化静态成员变量时,需要使用类名加作用域解析运算符 ::,并且不能再次使用 static 关键字。例如:

int MyClass::x = 10;    // 定义并初始化静态成员变量 x

访问静态成员变量
可以通过类名或类的实例来访问静态成员变量,使用时需要加上作用域解析运算符 ::。例如:

std::cout << MyClass::x << std::endl;   // 使用类名访问静态成员变量 x
MyClass obj;
std::cout << obj.x << std::endl;        // 使用类的实例访问静态成员变量 x

需要注意的是,由于静态成员变量属于整个类共享,因此不依赖于任何对象,可以在类的任何实例或者不创建实例的情况下访问。此外,静态成员变量的生命周期与程序的运行时间相同,因此只会有一份内存空间被分配,并且会在程序结束时自动销毁。

静态方法

静态方法没有类实例,静态方法也不能访问非静态变量
类外函数和静态方法需要给参数,就是函数名后的括号里要有参数;而类中的非静态方法不需要参数,已经有隐藏参数了。

【23】 Local Static

变量的生存期:表示变量实际存在的时间,也就是在它被删除之前,在内存中存在多久。
变量的作用域:表示可以访问的变量的范围

静态局部(local static)变量允许我们声明一个变量,它的生命周期基本相当于整个程序的生命周期,然而它的作用范围被限制在这个作用域内。
不仅仅存在函数中,也可以存在if语句,或者其他任何位置。
如果在函数作用域中声明一个静态变量,那么它将是那个函数的局部变量。
当函数内存在静态变量时,函数第一次被调用,该静态变量被初始化,并可供该函数的后续所有的调用提供同一变量,而不是创建新的变量。

函数中的local static

比如

void Function()
{   //这句的意思是当我第一次调用这个函数时它的值被初始化为0,后续调用不会再创建一个新的变量
 static int i = 0;
 i++;  //如果上一行没有static结果会是每次调用这个函数i的值被设为0,然后i自增1向控制台输出1
 std::cout << i << std::endl;
}

int main()
{
 Function();
 Function();
 Function();
 std::cin.get()
}

// 输出1,2,3

这其实就如同在函数外声明一个全局变量:

#include <iostream>
int i = 0;//声明一个全局变量
void Function()
{ 
 i++; 
 std::cout << i << std::endl;
}

int main()
{
 Function();
 Function();
 Function(); //输出 1 2 3
 std::cin.get()
}

//输出1,2,3

但这种存在的问题是,可以在任何地方访问到变量 i。

单例类中的local static

单例类是只存在一个实例的类。
如果不用local static:

class Singleton
{
private:
	static Singleton* s_Instance;  //声明指针静态成员变量
public:
	static Singleton& Get() { return *s_Instance; }

	void Hello() {}
};

Singleton* Singleton::s_Instance = nullptr;  //在类外部定义和初始化静态成员变量

int main() //程序的入口
{
	Singleton::Get().Hello();
	std::cin.get();
}

还有种方法可以简洁代码

class Singleton
{

public:
	static Singleton& Get() 
	{
		static Singleton instance;
		return instance; 
	}

	void Hello() {}
};

int main() //程序的入口
{
	Singleton::Get().Hello();
	std::cin.get();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值