類的靜態(static)成員

類有時候需要它的一些成員與類本身直接相關,而與類的各個對象之間無需保持聯繫,此時就可以將其聲明爲靜態成員。靜態成員屬於整個類,而不是某個對象。可以通過類名來直接調用其靜態成員,無需通過類的對象來進行訪問。靜態成員變量只存儲一份供所有對象共用。

1、靜態成員的聲明和定義

class Test
{
public:
	//帶默認形參的構造函數,默認的形參必須在形參列表的最後。
	Test(int a=8, double b=9) :age(a), grade(b) {}

	int GetAge()
	{
		return age;
	}
	double GetGrade()
	{
		return grade;
	}

	static int id;

private:
	int age;
	double grade;

	//非常量靜態成員,必須在類中聲明,類外定義和初始化該成員
	static int count;
	//常量靜態成員則必須要在聲明的時候進行初始化,因爲其是常量,後期不可以修改。
	static const int phone=123;

};

// 非常量靜態成員在類外進行定義和初始化,此時無需 static 關鍵字
int Test::id = 101;
int Test::count = 666;

// 即使一個常量靜態成員在類內部進行初始化,通常情況下也應該在類外再定義一下該成員。
const int Test::phone;



int main()
{
	Test test01;
	
	int num1, num2;
	//因爲靜態成員屬於類,所以可以直接通過類名來訪問公有的靜態成員,不可以直接訪問私有靜態成員。
	num1 = Test::id;
	// 也可以通過類的對象來訪問類的公有靜態成員。
	num2 = test01.id;
}
  • 靜態成員必須在類中聲明,在類外進行定義(因爲靜態成員屬於整個類,而不屬於某個對象,如果在類內初始化,會導致每個對象都包含該靜態成員)。當在類外部定義靜態成員時,不能再重複 static 關鍵字。
  • 因爲類的靜態成員存在於任何對象之外,所以對象中不包含任何靜態成員。如Test類的對象中只有 age、grade、GetAge()、GetGrade() 這四個成員,而不包含 id、count、phone 這三個靜態成員。
  • 可以使用作用域運算符通過類名直接訪問類的公有靜態成員,但不能直接訪問類的公有非靜態成員。
  • 雖然靜態成員屬於類,但是也可以通過類的對象來訪問公有靜態成員 test01.id;
  • 通常情況下類的靜態成員不應該在類的內部進行初始化,但是當該靜態成員爲const類型時,就必須在類中進行初始化。如:static const int phone=123;則必須在類中進行初始化。
  • 靜態成員函數中不能使用非靜態成員;但非靜態成員函數中可以使用靜態成員。因爲靜態成員函數屬於整個類,在類實例化對象之前就已經分配空間了,而類的非靜態成員必須在類實例化對象後纔有內存空間,所以靜態成員函數調用非靜態成員會出錯,就好比沒有聲明一個變量卻提前使用它一樣。

2、靜態成員能用於某些場景,而普通成員不能

class B
{
private:
	static B m1; //正確:靜態成員可以是不完全類型
	B *m2;  // 正確:指針成員可以是不完全類型
	B m3;  // 錯誤:數據成員必須是完全類型
};
  • 靜態成員可以是不完全類型
  • 靜態數據成員的類型可以就是它所屬的類類型。
  • 非靜態數據成員只能聲明成它所屬類的指針或引用
  • 非靜態數據成員不能作爲默認實參,因爲它本身屬於對象的一部分。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章