静态成员
概念
- 引入:实现一个类的不同对象
- 该类的所有对象共享静态成员
- 目的:实现数据共享,可以不必使用全局变量
- 静态数据成员
- 关键词:
static
- 该类的所有对象维护该对象的同一个拷贝
- 必须在类外定义和初始化,用
::
来指明所属的类 - 私有静态数据成员不能被类外部函数访问,也不能用对象访问
- 关键词:
- 静态成员函数
- 类外代码,使用类名和作用域操作符调用公有静态成员函数
- 静态成员函数只能引用属于该类的静态数据成员或静态成员函数
- 访问非静态数据成员,必须通过参数传递方式得到对象名,用过对象名访问
静态数据成员
定义:static 数据类型 数据成员名;
特点:
- 不论建立多少个类的对象,只有一个静态数据的拷贝
- 不因对象的建立而产生,不因对象的析构而删除
- 是类定义的一部分,不破坏类的隐蔽性
- 在类的声明中只能声明静态数据成员的存在
- 由于类的声明是抽象的,静态数据成员的初始化需要在类的外部进行,通过类名对它进行访问
- 静态数据成员是类的成员,不是对象的成员
访问:
- 只能访问公有静态数据成员
- 类名访问
<类名>::<静态成员名>
- 对象访问
<对象名>.<静态数据成员>
,<对象指针>-><静态数据成员>
初始化:
- 位置:一般在类定义后,
main()
前 <数据类型><类名>::<静态数据成员名>=<值>;
- 初始化时,不加访问权限控制符
#include <iostream>
#include <string.h>
using namespace std;
class student
{
private:
char *name;
char *stu_no;
float score;
static int count;
static float sum;
static float average;
public:
student(char* nameIn,char *stu_noIn,float scoreIn){
name = new char[strlen(nameIn) + 1];
strcpy(name, nameIn);
stu_no = new char[strlen(stu_noIn) + 1];
strcpy(stu_no, stu_noIn);
score = scoreIn;
count++;
sum += score;
average = sum / count;
}
void show(){
cout << "name:" << name << endl
<< "stu_no:" << stu_no << endl
<< "score:" << score << endl;
}
void show_count_sum_average(){
cout << "count:" << count << endl
<< "sum:" << sum << endl
<< "average:" << average << endl;
}
};
int student::count = 0;
float student::sum = 0;
float student::average = 0;
int main()
{
student stu1("Li Ming", "990201", 91),
stu2("Zhang San", "990318", 89);
stu1.show();
stu2.show();
stu1.show_count_sum_average();
return 0;
}
/*
output:
name:Zhang San
stu_no:990318
score:89
count:2
sum:180
average:90
*/
#include <iostream>
using namespace std;
class A
{
public:
static int x;
int get() { return x; }
};
int A::x = 0;
int main()
{
A::x = 200;
A ob1, ob2;
cout << "ob1.i=" << ob1.get() << endl
<< "ob2.i=" << ob2.get() << endl;
ob1.x = 300;
cout << "ob1.i=" << ob1.get() << endl
<< "ob2.i=" << ob2.get() << endl;
return 0;
}
/*
ob1.i=200
ob2.i=200
ob1.i=300
ob2.i=300
*/
静态成员函数
目的:在对象建立之前处理静态数据成员或全局变量
- 通过定义和使用静态成员函数可以访问静态数据成员
- 使用
static
关键词声明函数成员 - 静态成员函数属于整个类,由所有对象共享和共同维护
- 公有静态成员函数,可以通过类名或对象名调用
- 静态成员函数可以直接访问该类的静态数据成员和函数成员
- 访问非静态数据成员,必须通过参数传递方式得到对象名,然后通过对象名访问
定义:
static <返回类型> <静态成员函数名>(参数表);
调用:
<类名>::<静态成员函数>(名实参表)
<对象>.<静态成员函数>(名实参表)
<对象指针>-><静态成员函数>(名实参表)
#include <iostream>
#include <string.h>
using namespace std;
class student
{
private:
char *name;
char *stu_no;
float score;
static int count;
static float sum;
public:
student(char*nameIn,char*stu_noIn,float scoreIn){
name = new char[strlen(nameIn) + 1];
strcpy(name, nameIn);
stu_no = new char[strlen(stu_noIn) + 1];
strcpy(stu_no, stu_noIn);
score = scoreIn;
count++;
sum += score;
}
~student(){
delete[] name;
delete[] stu_no;
count--;
sum -= score;
}
void show(){
cout << "name:" << name << endl
<< "stu_no:" << stu_no << endl
<< "score:" << score << endl;
}
static void show_count_sum(){
cout << "count:" << count << endl
<< "sum:" << sum << endl;
}
};
int student::count = 0;
float student::sum = 0;
int main()
{
student stu1("Li Ming", "990201", 91);
stu1.show();
stu1.show_count_sum();
student stu2("Zhang San", "990318", 89);
stu2.show();
stu2.show_count_sum();
student::show_count_sum();
return 0;
}
/*
name:Li Ming
stu_no:990201
score:91
count:1
sum:91
name:Zhang San
stu_no:990318
score:89
count:2
sum:180
count:2
sum:180
*/
【attention】
- 静态数据成员可以定义成内嵌的,也可以在类外定义;类外定义时不能用
static
前缀 - 静态成员函数主要用来访问全局变量或同类中的静态数据成员;当与静态数据成员一起使用,达到对同一个对象之间共享数据进行维护的目的
- 私有静态成员函数不能被类外部函数和对象访问
- 可以用它在建立任何对象之前处理静态数据成员,这是普通成员函数不能实现的
- 静态成员函数没有this指针,所以不能访问类中的非静态数据成员;可以通过对象名作为参数访问
【Example 1】静态成员函数访问非静态数据成员
#include <iostream>
using namespace std;
class small_cat
{
private:
double weight;
static double total_weight;
static double total_number;
public:
small_cat(double w){
weight = w;
total_weight += w;
total_number++;
}
static void display(small_cat&x) // 访问非静态成员
{
cout << "the small_cat weights " << x.weight << "kg" << endl;
}
static void total_display() // 访问静态成员
{
cout << total_number << " small_cat, total_weight " << total_weight << "kg" << endl;
}
};
double small_cat::total_weight = 0;
double small_cat::total_number = 0;
int main()
{
small_cat w1(0.9),w2(0.8),w3(1.1);
small_cat::display(w1);
small_cat::display(w2);
small_cat::display(w3);
small_cat::total_display();
return 0;
}
/*
the small_cat weights 0.9kg
the small_cat weights 0.8kg
the small_cat weights 1.1kg
3 small_cat, total_weight 2.8kg
*/
【Example 2】普通指针访问静态数据成员
#include <iostream>
using namespace std;
class myclass
{
public:
myclass() { count++; }
static int count;
};
int myclass::count = 0;
int main()
{
int *p = &myclass::count;
myclass ob1, ob2, ob3, ob4;
cout << "myclass::count=" << *p << endl;
return 0;
}
/*
myclass::count=4
*/
【Example 3】指针访问静态成员函数
#include <iostream>
using namespace std;
class myclass
{
public:
myclass() { count++; }
static int get() { return count; }
static int count;
};
int myclass::count = 0;
int main()
{
int (*get)() = myclass::get;
myclass ob1, ob2, ob3, ob4;
cout << "myclass::count=" << (*get)() << endl;
return 0;
}
/*
myclass::count=4
*/