1:在函数内部定义静态变量(内部数据类型)
void fun() {
static int i = 0; //static 变量
i++;
int m = 0;
m++;
cout << "static i: " << i << endl;
cout << "local m: " << m << endl;
}
int main() {
fun();
fun();
}
程序运行输出结果:
static i: 1
local m: 1
static i: 2
local m: 1
这样的结果很好理解,静态变量在函数调用结束的时候不会被收回,而且仅在第一次调用函数的时候初始化。对于内部类型(int,char……)如果在声明的时候没有定义初值,系统会自动赋0值
2:在函数内部定义静态对象
对于静态对象,如果在声明的时候没有赋初值,那系统只能调用其缺省的构造函数,如果类不能调用缺省构造(私有构造),则必须自行初始化,看下面程序
class obj {
public:
obj() {
cout << "obj::obj()" << endl;
}
obj(int i) {
cout << "obj::obj(int i = 0)" << endl;
}
~obj() {
cout << "obj::~obj() " << endl;
}
};
void fun() {
static obj x; //obj类必须有缺省构造函数
static obj x2(1); //可以初始化该对象
}
int main() {
fun();
fun();
}
输出结果:
obj::obj()
obj::obj(int i = 0)
obj::~obj()
obj::~obj()
在函数一共调用了两次fun,但是x和x2仅进行了一次初始化。
3:类中的静态数据成员
类的静态数据成员代表了该类的所有 对象实例只使用一个共用的静态变量,无论这个类产生了多少对象,看下面的程序和输出的内容:
class obj {
public:
obj(char* str) {
cout << str << ": obj(); size: " <<size << endl;
}
void set(int i =0) {
if(i != 0) {
size = i;
}
}
void print() const {
cout <<" size: " << size << endl;
}
private:
static int size;
};
int obj::size = 100; //必须用这样的方式初始化
void fun() {
obj x1("x1");
x1.print();
x1.set(200);
x1.print();
obj x2("x2");
x2.set(300);
x2.print();
x1.print();
}
int main() {
fun();
}
输出结果:
x1: obj(); size: 100
size: 100
size: 200
x2: obj(); size: 200
size: 300
size: 300
看输出的内容很快就会明白,x1和x2使用的是同一个 size
3:类中静态常量和静态数组
明白了类中静态变量的意思那静态常量已经静态常量数组就很快能明白,只是他们的初始化方式有些不同之处,看下面的代码:
class Me {
static int m_length;
static const int size = 100; //仅内部类型可以在类内部定义静态常量
static const int number;
static int m_tips[];
static const int array[];
};
//初始化静态成员
//必须为所有类静态对象提供外部定义,包括静态数组和静态常量数组
//由于是默认内部编译联接,可以在头文件中提供这些定义
int Me::m_length = 99;
const int Me::number = 200;
int Me::m_tips[] = {1,2,3,4,5};
const int array[] = {1,2,3,4,5};
对于嵌套类可以有静态成员,定义方式仅需要额外的加上类限定符就可以了,函数内部的局部类不可以有静态成员。
4:类中静态成员函数
类的静态成员函数和静态数据成员类似,它服务于类的全体对象。静态成员函数由于没有接收当前对象的地址(this),它就无法访问一般的非静态成员,也就是说,static成员函数只能使用静态数据成员和静态成员函数,关于静态成员函数和类成员的关系看下面的代码:
class XX {
public:
XX(int m = 0) : i(m) {
add();
j = i;
j++;
//普通成员函数可以调用静态函数和成员
}
int fun() {
j++;
return i = j;
}
static int add() {
return j++;
// i++; 不可以这样作,理由是静态成员函数仅能访问静态数据
}
static int get() {
// fun(); 不可以这样作,理由是静态成员函数仅能访问静态数据
return add();
}
private:
int i;
static int j;
};
int XX::j = 0;
int main() {
XX x;
XX* px = &x;
//静态成员函数调用方式,意义相同
x.add();
px->add();
XX::add();
}
|