(欢迎大家关注我的微信公众号——控制工程研习,上面会分享很多我学习过程中总结的笔记。)
1. 介绍一下static关键字都有什么作用?都可以修饰什么?分别起到什么作用呢?
作用:
(1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变;
(2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量;
(3)在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。
可以修饰什么 & 具体作用:
(1)修饰局部变量
static修饰局部变量时,使得被修饰的变量成为静态变量,存储在静态区(对比:动态存储变量是在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放,比如不加static修饰的局部变量)。存储在静态区的数据生命周期与程序相同,在main函数之前初始化,在程序退出时销毁。(无论是局部静态还是全局静态)
一个简单的测试:
#include<iostream>
int test(){
static int a = 1;
a += 1;
return a;
}
int main()
{
std::cout << test() << std::endl;
std::cout << test() << std::endl;
}
可以发现static修饰的局部变量也会静态存储起来。
(2)修饰全局变量
全局变量本来就存储在静态区,因此static并不能改变其存储位置。但是,static限制了其链接属性。被static修饰的全局变量只能被该包含该定义的文件访问(即改变了作用域)。
(3)修饰函数
static修饰函数使得函数只能在包含该函数定义的文件中被调用。对于静态函数,声明和定义需要放在同一个文件夹中。
(4)修饰成员变量
用static修饰类的数据成员使其成为类的全局变量,会被类的所有对象共享,包括派生类的对象,所有的对象都只维持同一个实例。这个变量不属于对象私有,而是对象共享的。
因为构造函数是初始化对象所占空间(即对象私有),static修饰的成员变量不属于对象私有,因此不能用构造函数进行初始化因此,static成员必须在类外进行初始化(初始化格式:int base::var=10;),而不能在构造函数内进行初始化,不过也可以用const修饰static数据成员在类内初始化。
不加const不行,报错——带有类内初始化表达式的静态数据成员必须具有不可变的常量整型类型。否则只能类外初始化:
(5)修饰成员函数
用static修饰成员函数,使这个类只存在这一份函数,所有对象共享该函数,不含this指针,因而只能访问类的static成员变量,如果访问非static成员变量,就会报错:
静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。使用示例:
#include<iostream>
class base {
public:
static void display()
{
std::cout << "a = " << a << std::endl;
}
private:
static int a;
};
int base::a = 1;
int main()
{
// 无需实例,直接通过类访问
base::display();
}
例如可以封装某些算法,比如数学函数,如ln,sin,tan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好,比如定义一个数学函数类Math,调用Math::sin(3.14)。