静态成员数据是某一个类所具有的属性,而不是某一个对象的属性,所以它的存在并不依赖于对象。那么,如果一个类没有任何对象实例时,所有的普通成员函数都无法使用,我们该如何访问私有的静态成员数据呢?
既然成员数据可以属于某一个类而不属于某一个具体的对象,成员函数能否这样呢?答案是肯定的。在C++中,除了有静态成员数据,还有静态成员函数。静态成员函数也是属于某一个类而不属于某一个具体的对象的。静态成员函数的声明方法为:
static 返回值类型函数名(参数表);
不过,在声明静态成员函数时,却不能出现static。
下面我们就来看一下静态成员数据、静态成员函数在程序中如何使用:(程序16.1)
//node.h
- class Node//声明一个链表结点类
- {
- public:
- Node();//构造函数的声明
- Node(Node &n);
- Node(int i,char c='0');
- Node(int i,char c,Node *p,Node *n);
- ~Node();//析构函数
- int readi() const;
- char readc() const;
- Node * readp() const;
- Node * readn() const;
- bool set(int i);
- bool set(char c);
- bool setp(Node *p);
- bool setn(Node *n);
- static int allocation();//静态成员函数定义,返回已分配结点数
- private:
- int idata;//存储数据保密
- char cdata;//存储数据保密
- Node *prior;//前驱结点的存储位置保密
- Node *next;//后继结点的存储位置保密
- static int count;//静态成员数据,存储分配结点个数
- };
//node.cpp,把类声明和定义拆分开了
- #include "node.h"//如果没包含头文件连接时会出现错误
- #include <iostream>
- using namespace std;
- int Node::count=0;//静态成员数据初始化
- //未定义的函数与程序15.5相同
- Node::Node()//构造函数的定义
- {
- cout <<"Node constructor is running..." <<endl;
- count++;//分配结点数增加
- idata=0;
- cdata='0';
- prior=NULL;
- next=NULL;
- }
- Node::Node(int i,char c)//构造函数重载1
- {
- cout <<"Node constructor is running..." <<endl;
- count++;//分配结点数增加
- idata=i;
- cdata=c;
- prior=NULL;
- next=NULL;
- }
- Node::Node(int i,char c,Node *p,Node *n)//构造函数重载2
- {
- cout <<"Node constructor is running..." <<endl;
- count++;//分配结点数增加
- idata=i;
- cdata=c;
- prior=p;
- next=n;
- }
- Node::Node(Node &n)
- {
- count++;//分配结点数增加
- idata=n.idata;
- cdata=n.cdata;
- prior=n.prior;
- next=n.next;
- }
- Node::~Node()
- {
- count--;//分配结点数减少
- cout <<"Node destructor is running..." <<endl;
- }
- int Node::allocation()//在定义静态成员函数时不能出现static
- {
- return count;//返回已分配结点数
- }
- //linklist.h同程序15.5
- //main.cpp
- #include "Linklist.h"
- #include <iostream>
- using namespace std;
- int main()
- {
- int tempi;
- char tempc;
- cout <<"请输入一个整数和一个字符:" <<endl;
- cin >>tempi >>tempc;
- Linklist a(tempi,tempc);
- a.Locate(tempi);
- a.Insert(1,'C');
- a.Insert(2,'B');
- cout <<"After Insert" <<endl;
- a.Show();
- cout <<"Node Allocation:" <<Node::allocation() <<endl;//调用静态成员函数
- Node b;
- cout <<"An independent node created" <<endl;
- cout <<"Node Allocation:" <<b.allocation() <<endl;//调用静态成员函数
- return 0;
- }
-
运行结果:
请输入一个整数和一个字符:
3 F
Node constructor is running...
Linklist constructor is running...
Node constructor is running...
Node constructor is running...
After Insert
3 F
2 B
1 C
Node Allocation:3
Node constructor is running...
An independent node created
Node Allocation:4
Node destructor is running...
Linklist destructor is running...
Node destructor is running...
Node destructor is running...
Node destructor is running...
可见,记录结点分配情况的功能已经实现。该程序中出现了两种调用静态成员函数的方法,一种是类名::静态成员函数名(参数表),另一种是对象名.静态成员函数名(参数表),这两种调用方法的效果是相同的。由于静态成员函数是属于类的,不是属于某一个具体对象,所以它分不清到底是访问哪个对象的非静态成员数据,故而不能访问非静态成员数据。
在第11章中,我们遇到过保留字static,其作用是使局部变量在函数运行结束后继续存在,成为静态变量。(或者说存储空间在编译时静态分配)而本章中static的含义是“每个类中只含有一个”,与第11章中的static毫不相关。所以说这里的static是名不符实的。