靜態成員的提出是為瞭解決資料共用的問題。實現共用有許多方法,如:設定全域性的變數或對象是一種方法。但是,全域變數或對象是有局限性的。這一章裡,我們主要講述類的靜態成員來實現資料的共用。
待用資料成員
在類中,靜態成員可以實現多個對象之間的資料共用,並且使用待用資料成員還不會破壞隱藏的原則,即保證了安全性。因此,靜態成員是類的所有對象中共用的成員,而不是某個對象的成員。
使用待用資料成員可以節省記憶體,因為它是所有對象所公有的,因此,對多個對象來說,待用資料成員只儲存一處,供所有對象共用。待用資料成員的值對每個對
象都是一樣,但它的值是可以更新的。只要對待用資料成員的值更新一次,保證所有對象存取更新後的相同的值,這樣可以提高時間效率。
待用資料成員的使用方法和注意事項如下:
1、待用資料成員在定義或說明時前面加關鍵字static。
2、靜態成員初始化與一般資料成員初始化不同。待用資料成員初始化的格式如下:
<資料類型><類名>::<待用資料成員名>=<值>
這表明:
(1) 初始化在類體外進行,而前面不加static,以免與一般靜態變數或對象相混淆。
(2) 初始化時不加該成員的存取權限控制符private,public等。
(3) 初始化時使用範圍運算子來標明它所屬類,因此,靜態數
據成員是類的成員,而不是對象的成員。
3、待用資料成員是靜態儲存的,它是靜態生存期,必須對它進行初始化。
4、引用待用資料成員時,採用如下格式:
<類名>::<靜態成員名>
如果待用資料成員的存取權限允許的話(即public的成員),可在程式中,按上述格式來引用待用資料成員。
下面舉一例子,說明待用資料成員的應用:
#include
class
Myclass
{
public
:
Myclass
(int
a
, int
b
, int
c
);
void
GetNumber
();
void
GetSum
();
private
:
int
A
, B
, C
;
static
int
Sum
;
};
int
Myclass
::Sum
=
0;
Myclass
::Myclass
(int
a
, int
b
, int
c
)
{
A
= a
;
B
= b
;
C
= c
;
Sum
+= A
+B
+C
;
}
void
Myclass
::GetNumber
()
{
cout
<<"Number="
<<<","
<<<","
<<
}
void
Myclass
::GetSum
()
{
cout
<<"Sum="
<<
}
void
main
()
{
Myclass
M
(3, 7,
10),N
(14, 9, 11);
M
.GetNumber
();
N
.GetNumber
();
M
.GetSum
();
N
.GetSum
();
}
從輸出結果可以看到Sum的值對M對象和對N對象都是相等的。這是因為在初始化M對象時,將M對象的三個int型資料成員的值求和後賦給了Sum,於是
Sum儲存了該值。在初始化N對象時,對將N對象的三個int型資料成員的值求和後又加到Sum已有的值上,於是Sum將儲存另後的值。所以,不論是通過
對象M還是通過對象N來引用的值都是一樣的,即為54。
靜態成員函數
靜態成員函數和待用資料成員一樣,它們都屬於類的靜態成員,它們都不是對象成員。因此,對靜態成員的引用不需要用對象名。
在靜態成員函數的實現中不能直接引用類中說明的非靜態成員,可以引用類中說明的靜態成員。如果靜態成員函數中要引用非靜態成員時,可通過對象來引用。下面通過例子來說明這一點。
#include
class
M
{
public
:
M
(int
a
) { A
=a
; B
+=a
;}
static
void
f1
(M
m
);
private
:
int
A
;
static
int
B
;
};
void
M
::f1
(M
m
)
{
cout
<<"A="
<<;
cout
<<"B="
<<;
}
int
M
::B
=0;
void
main
()
{
M
P
(5),Q
(10);
M
::f1
(P
); file
://
調用時不用對象名
M
::f1
(Q
);
}
讀者可以自行分析其結果。從中可看出,調用靜態成員函數使用如下格式:
<類名>::<靜態成員函數名>(<參數表>);
一個類的靜態成員函數不能像非靜態成員函數那樣“預設調用”它的非靜態成員函數(因為靜態成員函數沒有隱含的this參數
)。在一個類的靜態成員函數中,
只要通過某種方式得到了一個指向本類型的對象的指標,並且有合適的access level, 就可以對此對象調用其非靜態成員函數.
1.用來儲存對象的個數。
2.作為一個標記,標記一些動作是否發生,比如:檔案的開啟狀態,印表機的使用狀態,等等。
3.儲存鏈表的第一個或者最後一個成員的記憶體位址。
靜態成員函數的作用基本上相當於一個帶有命名空間的全域函數。
1、你不需要產生一個對象的執行個體就可以直接使用該函數。如,Cxxx::MyStaticFunc();
2、視窗回呼函數需使用靜態成員函數或全域函數。
3、線程調用需使用靜態成員函數或全域函數。