C++的靜態成員變量和靜態成員函數

C++的靜態成員變量和靜態成員函數

靜態成員變量和靜態成員函數算是C++面向對象編程中的一個重點和難點,這裏的靜態具體指什麼呢?與普通的成員變量和成員函數相比,靜態成員函數和靜態成員變量是屬於類的,而不是屬於對象的,也就是說,在類實例化爲對象之前,靜態成員變量和靜態成員函數就已經分配了內存空間了,而普通成員函數和成員變量只有在對象產生之後纔會分配空間。下面我們來詳細看看他們的用法

(一)靜態成員變量

1.在類中聲明靜態數據成員只要加上static關鍵字即可:

class A{
private:
	static int a;
	//這樣a就是類A的靜態成員變量了
};

特別注意:在使用靜態成員變量之前一定要初始化。初始化靜態成員變量,必須在全局作用域中定義,如果定義的時候不給出初值,則默認初值爲0。當然,靜態成員變量在類中只能聲明而不能定義的。

2.靜態成員變量不屬於任何對象,靜態成員變量是由類的所有對象共享的

靜態成員變量只存儲一份供所有對象共用,所以在所有對象中都可以共享它的值,使用靜態成員變量實現多個對象之間的數據共享不會破壞隱藏的原則,保證了安全性還可以節省內存。
下面我們來看一個小例子:

class A {
public:
	static int a;
};
int A::a = 0;

int main() {
	A temp0;
	temp0.a = 5;
	A temp1;
	cout << temp0.a << endl;
	cout << temp1.a << endl;
}

很顯然輸出結果是兩個5,這也很容易說明靜態成員變量是所有對象共享的,他的值在這個類中的任何一個對象中都相同。

3.靜態成員變量在const函數中可以修改

class A {
public:
	static int a;
	int b;
	void changea(int i) const {
		this->a = i;
	}
	/*void changeb(int j) const {
		this->b = j;
	}*/
	//很顯然,這段被註釋的代碼會報錯
};
int A::a;

int main() {
	A temp0;
	temp0.changea(6);
}

cosnt函數的作用是保護調用這個const函數的對象(即this指針指向的對象)的所有普通成員變量,使其不能被修改,但是靜態成員變量不屬於任何對象,所以可以修改。

(二)靜態成員函數

靜態成員函數的聲明很簡單,只要在類的成員函數前加上static關鍵字即可,靜態成員函數也是屬於類的,它並不屬於任何對象。靜態成員函數中是不能訪問本類中的非靜態成員變量的,所以在c++中,靜態成員函數的主要功能就是訪問靜態成員變量。當然,非靜態成員函數也可以訪問靜態成員變量。

下面我們來看一個例子:

class A {
public:
	static int a;
	int b;
	static void showa(){
		cout << a << endl;
	}
	/*static void showb() {
		cout << b << endl;
	}*/
	//這段被註釋的代碼會報錯
};
int A::a = 9;

int main() {
	A temp0;
	temp0.showa();
}

很明顯我們可以看出靜態成員函數無法訪問非靜態成員變量。

下面列出使用靜態成員函數的幾個注意點:

1.靜態成員函數不能調用非靜態成員函數,但是非靜態成員函數可以調用靜態成員函數
2.靜態成員函數沒有this指針,也就是說靜態成員函數不能使用const修飾符
3.靜態成員函數的地址可用普通函數指針儲存,而普通成員函數地址需要用類成員函數指針來儲存。

靜態成員函數的一個優點是可以在任何類的實例被創建之前調用它們,這使得它們可以用來執行復雜的初始化任務,這些任務必須在創建類的對象之前完成。

總結一下:其實不論是靜態成員變量還是靜態成員函數,它們都是不依賴於對象而存在的。
對於非靜態成員變量和非靜態成員函數,類在定義之後並不爲他們分配存儲空間,而是在定義類的對象的時候才分配存儲空間。相反,靜態的成員變量和靜態的成員函數在定義類時已經在內存中開闢了內存空間,所以靜態成員變量可以被獨立的訪問(在任何對象沒有建立起來時都可以訪問),並且靜態成員函數不可以調用非靜態成員函數,因爲非靜態成員函數只有在類對象建立以後纔可以調用。

2019年5月22日

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章