C++教程:C++靜態(tài)成員函數(shù)
2020-05-23 14:25:46
供稿:網(wǎng)友
靜態(tài)成員數(shù)據(jù)是某一個(gè)類所具有的屬性,而不是某一個(gè)對(duì)象的屬性,所以它的存在并不依賴于對(duì)象。那么,如果一個(gè)類沒有任何對(duì)象實(shí)例時(shí),所有的普通成員函數(shù)都無法使用,我們?cè)撊绾卧L問私有的靜態(tài)成員數(shù)據(jù)呢?
既然成員數(shù)據(jù)可以屬于某一個(gè)類而不屬于某一個(gè)具體的對(duì)象,成員函數(shù)能否這樣呢?答案是肯定的。在C++中,除了有靜態(tài)成員數(shù)據(jù),還有靜態(tài)成員函數(shù)。靜態(tài)成員函數(shù)也是屬于某一個(gè)類而不屬于某一個(gè)具體的對(duì)象的。靜態(tài)成員函數(shù)的聲明方法為:
static 返回值類型函數(shù)名(參數(shù)表);
不過,在聲明靜態(tài)成員函數(shù)時(shí),卻不能出現(xiàn)static。
下面我們就來看一下靜態(tài)成員數(shù)據(jù)、靜態(tài)成員函數(shù)在程序中如何使用:(程序16.1)
//node.h
class Node//聲明一個(gè)鏈表結(jié)點(diǎn)類
{
public:
Node();//構(gòu)造函數(shù)的聲明
Node(Node &n);
Node(int i,char c='0');
Node(int i,char c,Node *p,Node *n);
~Node();//析構(gòu)函數(shù)
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();//靜態(tài)成員函數(shù)定義,返回已分配結(jié)點(diǎn)數(shù)
private:
int idata;//存儲(chǔ)數(shù)據(jù)保密
char cdata;//存儲(chǔ)數(shù)據(jù)保密
Node *prior;//前驅(qū)結(jié)點(diǎn)的存儲(chǔ)位置保密
Node *next;//后繼結(jié)點(diǎn)的存儲(chǔ)位置保密
static int count;//靜態(tài)成員數(shù)據(jù),存儲(chǔ)分配結(jié)點(diǎn)個(gè)數(shù)
};
//node.cpp,把類聲明和定義拆分開了
#include "node.h"//如果沒包含頭文件連接時(shí)會(huì)出現(xiàn)錯(cuò)誤
#include <iostream>
using namespace std;
int Node::count=0;//靜態(tài)成員數(shù)據(jù)初始化
//未定義的函數(shù)與程序15.5相同
Node::Node()//構(gòu)造函數(shù)的定義
{
cout <<"Node constructor is running..." <<endl;
count++;//分配結(jié)點(diǎn)數(shù)增加
idata=0;
cdata='0';
prior=NULL;
next=NULL;
}
Node::Node(int i,char c)//構(gòu)造函數(shù)重載1
{
cout <<"Node constructor is running..." <<endl;
count++;//分配結(jié)點(diǎn)數(shù)增加
idata=i;
cdata=c;
prior=NULL;
next=NULL;
}
Node::Node(int i,char c,Node *p,Node *n)//構(gòu)造函數(shù)重載2
{
cout <<"Node constructor is running..." <<endl;
count++;//分配結(jié)點(diǎn)數(shù)增加
idata=i;
cdata=c;
prior=p;
next=n;
}
Node::Node(Node &n)
{
count++;//分配結(jié)點(diǎn)數(shù)增加
idata=n.idata;
cdata=n.cdata;
prior=n.prior;
next=n.next;
}
Node::~Node()
{
count--;//分配結(jié)點(diǎn)數(shù)減少
cout <<"Node destructor is running..." <<endl;
}
int Node::allocation()//在定義靜態(tài)成員函數(shù)時(shí)不能出現(xiàn)static
{
return count;//返回已分配結(jié)點(diǎn)數(shù)
}
//linklist.h同程序15.5
//main.cpp
#include "Linklist.h"
#include <iostream>
using namespace std;
int main()
{
int tempi;
char tempc;
cout <<"請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符:" <<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;//調(diào)用靜態(tài)成員函數(shù)
Node b;
cout <<"An independent node created" <<endl;
cout <<"Node Allocation:" <<b.allocation() <<endl;//調(diào)用靜態(tài)成員函數(shù)
return 0;
}
運(yùn)行結(jié)果:
請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符:
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...
可見,記錄結(jié)點(diǎn)分配情況的功能已經(jīng)實(shí)現(xiàn)。該程序中出現(xiàn)了兩種調(diào)用靜態(tài)成員函數(shù)的方法,一種是類名::靜態(tài)成員函數(shù)名(參數(shù)表),另一種是對(duì)象名.靜態(tài)成員函數(shù)名(參數(shù)表),這兩種調(diào)用方法的效果是相同的。由于靜態(tài)成員函數(shù)是屬于類的,不是屬于某一個(gè)具體對(duì)象,所以它分不清到底是訪問哪個(gè)對(duì)象的非靜態(tài)成員數(shù)據(jù),故而不能訪問非靜態(tài)成員數(shù)據(jù)。
名不符實(shí)的static
在第11章中,我們遇到過保留字static,其作用是使局部變量在函數(shù)運(yùn)行結(jié)束后繼續(xù)存在,成為靜態(tài)變量。(或者說存儲(chǔ)空間在編譯時(shí)靜態(tài)分配)而本章中static的含義是“每個(gè)類中只含有一個(gè)”,與第11章中的static毫不相關(guān)。所以說這里的static是名不符實(shí)的。