C++教程:C++靜態成員函數
2020-05-23 14:25:46
供稿:網友
靜態成員數據是某一個類所具有的屬性,而不是某一個對象的屬性,所以它的存在并不依賴于對象。那么,如果一個類沒有任何對象實例時,所有的普通成員函數都無法使用,我們該如何訪問私有的靜態成員數據呢?
既然成員數據可以屬于某一個類而不屬于某一個具體的對象,成員函數能否這樣呢?答案是肯定的。在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...
可見,記錄結點分配情況的功能已經實現。該程序中出現了兩種調用靜態成員函數的方法,一種是類名::靜態成員函數名(參數表),另一種是對象名.靜態成員函數名(參數表),這兩種調用方法的效果是相同的。由于靜態成員函數是屬于類的,不是屬于某一個具體對象,所以它分不清到底是訪問哪個對象的非靜態成員數據,故而不能訪問非靜態成員數據。
名不符實的static
在第11章中,我們遇到過保留字static,其作用是使局部變量在函數運行結束后繼續存在,成為靜態變量。(或者說存儲空間在編譯時靜態分配)而本章中static的含義是“每個類中只含有一個”,與第11章中的static毫不相關。所以說這里的static是名不符實的。