【整理归纳】static const extern
static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0。
static 声明的变量在C语言中有两方面的特征:
- 变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
- 变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
【特性】
1、静态成员为所有类对象所共享,不属于某个具体的实例。
2、类静态成员即可用类名::静态成员或者对象.静态成员来访问
3、类静态成员变量必须在类外定义,定义时不添加static关键字
4、类的静态成员函数没有默认的this指针,因此在它里面不能使用任何非静态成员
5、静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值,const修饰符等参数。

Tips:
A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;
D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
- 静态成员函数可以调用非静态成员函数吗?
不能。 静态成员函数没有this指针,是所有类对象公有的。成员函数有this指针,每个对象都有自己独立的一份。在调用成员函数时,实际上是this->成员函数。一个类的静态成员中去访问其非静态成员之所以会出错是因为在类的非静态成员不存在的时候类的静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。 - 非静态成员函数可以调用类的静态成员函数吗?
可以。 非静态成员(变量和方法)属于类的对象,所以只有在类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。
- 常量变量
const 类型说明符 变量名 - 常引用
const 类型说明符 &引用名 - 常对象
类名 const 对象名 - 常成员函数
类名::fun(形参) const - 常数组
类型说明符 const 数组名[大小] - 常指针
const 类型说明符 指针名*
类型说明符 const 指针名*
【const使用场景】
- const修饰形参,一般和引用同时使用
- const修饰返回值
- const修饰类数据成员,必须在构造函数的初始化列表中初始化
- const修饰类成员函数,实际修饰隐含的this,表示在类中不可以对类的任何成员进行修改
- 在const修饰的成员函数中要对类的某个数据成员进行修改,该数据成员定义声明是必须加mutable关键字
const修饰this指针不能改变
- const对象可以调用非const成员函数和const成员函数吗?
不能。调用非const成员函数(如果调用非const则与const相矛盾),可以调用const成员函数。 - 非const对象可以调用非const成员函数和const成员函数吗?
都可以调用。 - const成员函数内可以调用其它的const成员函数和非const成员函数吗?
不能。调用其它的非const成员函数,可以调用其它的const成员函数。 - 非const成员函数内可以调用其它的const成员函数和非const成员函数吗?
都可以调用。
在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。
file1.cpp
int num=10;
file2.cpp
#include<iostream>
using namespace std;
extern int num;
int main()
{
cout << num << endl;
return 0;
}
在file2中如果想调用file1中的变量num,只须用extern进行声明即可调用num,这就是extern的作用。在这里要注意extern声明的位置对其作用域也有关系,如果是在main函数中进行声明的,则只能在main函数中调用,在其它函数中不能调用。