一.全局静态变量 no-local static(全局变量前加static关键字)
- 全局静态变量储存在静态存储区,在程序运行期间一直存在。
- 初始化:未经初始化的全局静态变量自动初始化为0(静态全局对象值随机)
- 作用域:在声明它的文件之外不可见,从定义之处开始,到文件结尾。
二.局部静态变量 local static(局部变量前加static)
- 同no-local static一样储存在静态存储区。
- 初始化:等同于no-local static.
- 作用域:为局部作用域, 函数或语句块结束时结束。但当local static离开作用域后并未被销毁,仍驻留在内存中,只不过不能再对它访问,直到该函数再次被调用,并且值不变。
- 区别:静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
- 下面是局部静态变量为什么值不会变的例子:
#include <iostream>
using namespace std;
void sum(int a, int b){
static int add = 0;
add = a + b;
cout << add << endl;
}
int main(){
sum(1, 2);
sum(2, 3);
}
输出结果为:
3
5
- 从这个例子可以看出主函数中第一个sum函数的调用使local static add的值变为了3,但当第一个sum函数体结束后,add并未被销毁且值变为了初始化时的值,于是第二个sum函数得到了正确的解。
三.静态函数(在函数返回类型前加static关键字)
- 函数的定义与声明在默认情况下为extern,而静态函数只在声明它的文件中可见,不可被其他文件使用。—只可在本cpp内使用,不会同其他cpp的同名函数引起冲突。
- warning:不要在头文件(.h)中声明static函数,不要在(.cpp)中声明非static函数。如果在多个cpp复用该函数,就把它的声明提到头文件(.h)中,否则代码复用需要在各个cpp内部声明加static关键字,且编写大量重复代码。
- 但由此也带来一个优点就是:其他文件中可以定义相同名字的函数,不会发生冲突。
四.类中的静态成员变量
- 优点:静态成员可以实现多个对象之间的数据共享,并且还不会破坏隐藏的原则,保证了安全性。公共静态数据成员可被类的外部访问,保护或私有静态数据成员只可被类的内部访问。
- 静态成员是类的所有对象*享的成员,而不是某个对象的成员。对多个对象来说,静态数据成员只存储一处,供所有对象共用。
五.类的静态成员函数
- 一个静态成员函数不与任何对象相联系,故不能对非静态成员进行默认访问,只可以引用类中声明的静态成员(important)。但如果静态成员函数要引用非静态成员,可通过对象来引用。
- 举例:
#include <iostream>
class Date{
public:
Date() = default;
Date(int month, int day, int year) {
this->month = month;
this->day = day;
this->year = year;
}
static display(Date date){
std::cout << date.month << " " << date.day << " " << date.year << std::endl;
}
private:
int month{5};
int day{21};
int year{2002};
};
int main(){
Date d;
Date::display(d);
}
- 最寻常的调用静态函数的格式:
<className>::<static function name>(参数名);
- 静态成员函数与非静态成员函数的根本区别是什么?他们的根本区别就是静态成员函数没有this指针,而非静态成员函数有一个指向当前对象的指针this。
六.友元函数(tips:这虽然不是这篇文章的主题,但已经说到了成员函数,就想把友元也说一下记录一下)
- 为什么需要友元?
有时,普通函数需要直接访问一个类的保护或者私有数据成员(主要为了提高效率和方便编程),若无友元机制,只能将类的数据成员声明为public,这严重违反了封装性即安全性,任何函数均可以无拘无束的访问它。 - 优点:<1>避免频繁调用成员函数,提高效率。
<2>方便重载操作符的使用。 - 友元函数可以声明在类的任何位置,但也仅仅只能声明它的函数原型(函数返回值前加friend),定义则在类的外部,一般与成员函数的定义在一起,因为类重用时,友元一起提供。
- 一个类的成员函数可以是另一个类的友元;整个类也可以是另一个类的友元,称为友类。友类中的每个成员函数都可访问另一个类中的保护数据成员(protected)和私有数据成员(private)