程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++靜態成員函數和靜態數據成員

C++靜態成員函數和靜態數據成員

編輯:C++入門知識

C++靜態成員函數和靜態數據成員


當將類的某個數據成員聲明為static時,該靜態數據成員只能被定義一次,而且要被同類的所有對象共享。各個對象都擁有類中每一個普通數據成員的副本,但靜態數據成員只有一個實例存在,與定義了多少類對象無關。靜態方法就是與該類相關的,是類的一種行為,而不是與該類的實例對象相關。 靜態數據成員的用途之一是統計有多少個對象實際存在。 靜態數據成員不能在類中初始化,實際上類定義只是在描述對象的藍圖,在其中指定初值是不允許的。也不能在類的構造函數中初始化該成員,因為靜態數據成員為類的各個對象共享,否則每次創建一個類的對象則靜態數據成員都要被重新初始化。 靜態成員不可在類體內進行賦值,因為它是被所有該類的對象所共享的。你在一個對象裡給它賦值,其他對象裡的該成員也會發生變化。為了避免混亂,所以不可在類體內進行賦值。 靜態成員的值對所有的對象是一樣的。靜態成員可以被初始化,但只能在類體外進行初始化。 一般形式: 數據類型類名::靜態數據成員名=初值 注意:不能用參數初始化表對靜態成員初始化。一般系統缺省初始為0。
靜態成員是類所有的對象的共享的成員,而不是某個對象的成員。它在對象中不占用存儲空間,這個屬性為整個類所共有,不屬於任何一個具體對象。所以靜態成員不能在類的內部初始化,比如聲明一個學生類,其中一個成員為學生總數,則這個變量就應當聲明為靜態變量,應該根據實際需求來設置成員變量。
#include "iostream" using namespacestd; class test { private: int x; int y; public: static int num; static int Getnum() { x+=5; //這行代碼是錯誤的,靜態成員函數不能調用非靜態數據成員,要通過類的對象來調用。 num+=15; return num; } }; int test::num = 10; int main(void) { test a; cout< //10 test::num = 20; cout< //20 cout< //35 cout< //50 system("pause"); return 0; } 通過上例可知: x+=5; // 這行代碼是錯誤的 靜態函數成員必須通過對象名來訪問非靜態數據成員。 另外,靜態成員函數在類外實現時候無須加static關鍵字,否則是錯誤的。 若在類的體外來實現上述的那個靜態成員函數,不能加static關鍵字,這樣寫就可以了: int test::Getnum() { ......... } 1、static成員的所有者是類本身和對象,但是多有對象擁有一樣的靜態成員。從而在定義對象是不能通過構造函數對其進行初始化。 2、靜態成員不能在類定義裡邊初始化,只能在classbody外初始化。 3、靜態成員仍然遵循public,private,protected訪問准則。 4、靜態成員函數沒有this指針,它不能返回非靜態成員,因為除了對象會調用它外,類本身也可以調用。

靜態成員函數可以直接訪問該類的靜態數據和函數成員,而訪問非靜態數據成員必須通過參數傳遞的方式得到一個對象名,然後通過對象名來訪問。


class Myclass
{
private:
int a,b,c;
static intSum; //聲明靜態數據成員
public:
Myclass(int a,int b,int c);
void GetSum();
};
intMyclass::Sum=0; //定義並初始化靜態數據成員
Myclass::Myclass(int a,int b,int c)
{
this->a=a;
this->b=b;
this->c=c;
Sum+=a+b+c;
}
void Myclass::GetSum()
{
cout <<"Sum="< }
int main(void)
{
Myclass me(10,20,30);
me.GetSum();
system("pause");
return 0;
}

由上例可知,非靜態成員函數可以任意地訪問靜態成員函數和靜態數據成員。
非靜態成員函數Myclass(inta,int b,int c)和GetSum()都訪問了靜態數據成員Sum。
靜態成員函數不能訪問非靜態成員函數和非靜態數據成員。


與靜態數據成員不同,靜態成員函數的作用不是為了對象之間的溝通,而是為了能處理靜態數據成員。

我們知道,當調用一個對象的成員函數(非靜態成員函數)時,系統會把該對象的起始地址賦給成員函數的this指針。而靜態成員函數並不屬於某一對象,它與任何對象都無關,因此靜態成員函數沒有this指針。既然它沒有指向某一對象,就無法對一個對象中的非靜態成員進行默認訪問(即在引用數據成員時不指定對象名)。

可以說,靜態成員函數與非靜態成員函數的根本區別是:非靜態成員函數有this指針,而靜態成員函數沒有this指針。由此決定了靜態成員函數不能訪問本類中的非靜態成員。

靜態成員函數可以直接引用本類中的靜態數據成員,因為靜態成員同樣是屬於類的,可以直接引用。在C++程序中,靜態成員函數主要用來訪問靜態數據成員,而不訪問非靜態成員。

關於靜態成員函數,可以總結為以下幾點:
出現在類體外的函數定義不能指定關鍵字static;
靜態成員之間可以相互訪問,包括靜態成員函數訪問靜態數據成員和訪問靜態成員函數;
非靜態成員函數可以任意地訪問靜態成員函數和靜態數據成員;
靜態成員函數不能訪問非靜態成員函數和非靜態數據成員;
由於沒有this指針的額外開銷,因此靜態成員函數與類的全局函數相比速度上會有少許的增長;
調用靜態成員函數,可以用成員訪問操作符(.)和(->)為一個類的對象或指向類對象的指針調用靜態成員函數,
當同一類的所有對象使用一個量時,對於這個共用的量,可以用靜態數據成員變量,這個變量對於同一類的所有的對象都取相同的值。靜態成員變量只能被靜態成員函數調用。靜態成員函數也是由同一類中的所有對象共用。只能調用靜態成員變量和靜態成員函數。

(總結:靜態成員函數只能訪問靜態數據成員,不能訪問非靜態數據成員;非靜態成員函數能訪問靜態數據成員和非靜態數據成員。(為了某些需求,比如可能某一個變量不屬於具體的對象,而是屬於類,那麼這個成員就是靜態數據成員),在使用時,盡可能使用靜態成員函數訪問靜態數據成員,這樣更加清晰)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved