一、静态成员函数:
通常,当说明一个对象时,把该类中的有关成员数据拷贝到该对象中,即同一个类的不同对象,其成员数据之间是互相独立的。
当我们将类的某一个数据成员的存储类型指定为静态类型时,则由该类所产生的所有对象,其静态成员均共享一个存储空间,这个空间是在编译的时候分配的。换而言之,在说明对象时,并不为静态类型的成员分配空间。
在类定义中,用关键字static修饰的数据成员称为静态数据成员。
【静态数据成员】
有关静态数据成员的使用,说明以下几点:
1)类的静态数据成员是静态分配存储空间的,而其它成员是动态分配存储空间的(全局变量除外)。当类中没有定义静态数据成员时,在程序执行期间遇到说明类的对象时,才为对象的所有成员依次分配存储空间,这种存储空间的分配是动态的;而当类中定义了静态数据成员时,在编译时,就要为类的静态数据成员分配存储空间。
2)必须在文件作用域中,对静态数据成员作一次且只能作一次定义性说明。因为静态数据成员在定义性说明时已分配了存储空间,所以通过静态数据成员名前加上类名和作用域运算符,可直接引用静态数据成员。在C++中,静态变量缺省的初值为0,所以静态数据成员总有唯一的初值。当然,在对静态数据成员作定义性的说明时,也可以指定一个初值。
例:
#include <iostream>
using namespace std;
class TestA
{
private:
int i, j;
static int x, y; //定义静态数据成员
public:
TestA(int a, int b, int c, int d) //构造函数
{
cout << " x=" << x << ", y=" << y << endl;
i = a;
j = b;
x = c;
y = d;
}
void dis_ijxy()
{
cout << " i=" << i << ", j=" << j << ", x=" << x << ", y=" << y << endl;
}
};
int TestA::x = 15; //静态成员定义性说明
int TestA::y = 23;
int main()
{
TestA test1(20,30,40,60);
test1.dis_ijxy();
TestA test2(200, 300, 400, 600);
test2.dis_ijxy();
return 0;
}
输出结果:
3)静态数据成员具有全局变量和局部变量的一些特性。静态数据成员与全局变量一样都是静态分配存储空间的,但全局变量在程序中的任何位置都可以访问它,而静态数据成员受到访问权限的约束。必须是public权限时,才可能在类外进行访问。
4)为了保持静态数据成员取值的一致性,通常在构造函数中不给静态数据成员置初值,而是在对静态数据成员的定义性说明时指定初值。
例:
#include <iostream>
using namespace std;
class Test
{
private:
int i;
static int count; //定义静态数据成员
public:
Test(int x = 5) //构造函数
{
i = x;
count++;
}
void dis()
{
cout << " i=" << i <<", count=" <<count << endl;
}
};
int Test::count = 0;//静态成员定义性说明
int main()
{
Test test1[100];
Test test2[10];
test1->dis(); // 输出 i=5, count=110
test2->dis(); // 输出 i=5, count=110
return 0;
}
输出结果:
【静态成员函数】
可以将类的成员函数定义为静态的成员函数。即使用关键字static来修饰成员函数 。
class Test
{
float x, y;
public :
Test( ){ }
static void sum(void) //静态成员函数
{ ..... }
};
对静态成员函数的用法说明以下几点:
1)与静态数据成员一样,在类外的程序代码中,通过类名加上作用域操作符,可直接调用静态成员函数。
2)静态成员函数只能直接使用本类的静态数据成员或静态成员函数,但不能直接使用非静态的数据成员 (可以引用使用)。这是因为静态成员函数可被其它程序代码直接调用,所以,它不包含对象地址的this指针。
3)静态成员函数的实现部分在类定义之外定义时,其前面不能加修饰词static。这是由于关键字static不是数据类型的组成部分,因此,在类外定义静态成员函数的实现部分时,不能使用这个关键字4)不能把静态成员函数定义为虚函数。静态成员函数也是在编译时分配存储空间,所以在程序的执行过程中不能提供多态性。
5)可将静态成员函数定义为内联的(inline),其定义方法与非静态成员函数完全相同。
例:
#include <iostream>
using namespace std;
//静态成员函数应用
class Test
{
private:
int x;
static int y; //定义静态数据成员
public:
Test(int a) //构造函数
{
x = a;
y = y + x;
}
static void dis(Test test1) //静态成员函数
{
cout << "x=" << test1.x << ", y=" << y << endl;
}
};
int Test::y = 10;//静态成员定义性说明
int main()
{
Test test2(5), test3(10), test4(40);
Test::dis(test2); //输出 x=5, y=65 //静态成员函数应用
Test::dis(test3); //输出 x=10, y=65
Test::dis(test4); //输出 x=40, y=65
return 0;
}
输出结果:
二、指向类的指针
一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算符 ->,就像访问指向结构的指针一样。与所有的指针一样,您必须在使用指针之前,对指针进行初始化。
例:
#include <iostream>
using namespace std;
class Test
{
private:
int x;
static int y; //定义静态数据成员
public:
Test(int a) //构造函数
{
x = a;
y = y + x;
}
inline static void dis(Test test1); //静态成员函数声明
};
int Test::y = 10;//静态数据成员定义性说明
void Test::dis(Test test1) //静态成员函数 在类外 定义
{
cout << " x=" << test1.x << ", y=" << y << endl;
}
int main()
{
Test test2(5), test3(10);
test2.dis(test2); //输出 x=5, y=25 //静态成员函数应用
test3.dis(test3); //输出 x=10, y=25
Test* pt = &test2;//定义一个类的指针,指向类的对象, (指向类的指针)
pt->dis(test2);
return 0;
}
输出结果: