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();
}