C语言中的static
主要是修饰变量或者函数
1、生命周期:
static修饰的变量,无论是在函数内还是函数外(局部变量还是全局变量),生命周期都是整个程序运行期间,static修饰的函数,其生命周期也是整个程序运行期间
2、作用域:
static修饰的局部变量,它的生命周期就是那一对{}之间
而static修饰的全局变量,它的作用域是当前文件,也就是说static修饰的变量是内部链接的,别的文件不可访问
static修饰的函数,其作用域也是当前文件
3、存储位置:
static修饰的变量存储位置都在全局区,初始化的变量存储在data段,未初始化的变量存储在BSS段
static修饰的函数存储在代码区
关于内存分区问题,如果不大明白可以看看http://blog.youkuaiyun.com/helloworld__2016/article/details/78153016
static修饰的变量默认初始化为0或者空(NULL)
C++中的static
除了有C语言中的特性外,还多了一些关于类的特性
在类定义中,它的成员(包括成员变量和成员函数),这些成员可以用关键字static声明为静态的,称为静态成员。不管这个类创建了多少个对象,静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。
1、静态成员变量
首先我们要知道关于静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间。
(1)静态成员变量必须在类中声明,在类外定义。(这句话很重要)
(2)静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占空间。
(3)静态数据成员可以通过类名或者对象名来引用。
2、静态成员函数
(1)静态成员函数的使用和静态成员变量一样
(2)静态成员函数内部只能存放静态成员变量,不能访问非静态的成员变量(普通成员变量)
(3)静态成员函数也有访问权限
(4)普通成员函数可以访问静态成员变量,也可以访问非静态成员变量
静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员,完成对静态数据成员的封装。
3、const静态成员属性
如果一个类的成员,既要实现共享,又要实现不可改变,那就用 static const 修饰。定义静态const数据成员时,最好在类内部初始化。
4、返回静态变量的引用
这一点主要体现在函数的返回类型是引用的时候,如果函数的返回值为引用,那么你return的不能是局部变量,因为局部变量只在返回的时候编译器做了优化而只保留一次数据,想要再操作就会出错了。这时候就需要静态变量了,因为静态变量的生命周期为整个程序运行期,所以完全可以作为引用类型的返回值。
下面是一个demo,如果对于上面那段话不大理解,那么可以看一看下面这段代码和运行结果
#include <iostream>
using namespace std;
int &test01()
{
int a = 10;
return a;
}
int &test02()
{
static int a = 10;
return a;
}
void main()
{
int &num1 = test01();
cout << "num1 第一次打印" << num1 << endl;
cout << "num1 第二次打印" << num1 << endl;
int &num2 = test02();
cout << "num2 第一次打印" << num2 << endl;
cout << "num2 第二次打印" << num2 << endl;
system("pause");
}
运行结果为:
静态成员的访问权限问题就是当静态成员在类中的权限是private,那么在类外也是不能访问它
#include <iostream>
using namespace std;
class Person
{
public:
static int a;
static void test01(int val)
{
a = val;
cout << "This is test01!" << endl;
};
private:
static int b;
static void test02()
{
cout << "This is test02!" << endl;
};
};
void main()
{
Person p1;
p1.a = 10;//ok
p1.b = 10;//err
p1.test01(100);//ok
p1.test02();//err
system("pause");
}
(个人整理,如有不正确的地方,欢迎评论。 代码是在VS编译器上测试的)