C++ 的 static -靜態變數與函式簡單範例1

複習上一篇:C++ 的 static -靜態變數與函式詳細說明
https://husking-studio.com/cpp-static/

再提醒一次
靜態成員變數所有物件共用的資料,甚至不需要有物件也能使用。
靜態成員函式可以存取靜態成員變數,也是不需要有物件就能呼叫。

這邊舉個簡單的例子。幾乎所有文章在介紹靜態變數時,都一定會使用「用來計算這個類別產生了多少物件」。

來寫一個學生類別,計算有多少學生。

student.h

#include <iostream>
using namespace std;

class Student
{
private:
	string m_strName;	//學生名字
	static int m_nAllStudentNum;	//學生總數(靜態成員變數)
public:
	Student(string strName);
	~Student();
private:
	static void AddAllStudentNum();//遞增學生總數
	static void MinusAllStudentNum();//遞減學生總數
public:
	string GetName();
	static int GetAllStudentNum();//取得學生總數
};

student.cpp

#include "student.h"

int Student::m_nAllStudentNum = 0;	//學生總數初始化為 0

Student::Student(string strName) 
{ 
	m_strName = strName; 
	Student::AddAllStudentNum();//遞增學生總數
}
Student::~Student() 
{ 
	Student::MinusAllStudentNum();//遞減學生總數
}
string Student::GetName() 
{ 
	return m_strName; 
}
void Student::AddAllStudentNum()//靜態成員函式-遞增學生總數
{
	m_nAllStudentNum++;
}
void Student::MinusAllStudentNum()//靜態成員函式-遞減學生總數
{
	if(m_nAllStudentNum > 0)
		m_nAllStudentNum--;
}
int Student::GetAllStudentNum() //靜態成員函式-取得學生總數
{ 
	return m_nAllStudentNum; 
}

特別注意 AddAllStudentNum() 和 MinusAllStudentNum() 這兩個成員函式,它們不只是靜態的,還被設成了 private 的,讓外面不能呼叫它們來修改學生總數。

main.cpp

int main()
{
	//一開始沒有學生
	cout << Student::GetAllStudentNum() << endl;//0

	//湯姆加入了
	Student* pTom = new Student("Tom");
	cout << Student::GetAllStudentNum() << endl;//1

	//麥朵加入了
	Student* pMyrtle = new Student("Myrtle");
	cout << Student::GetAllStudentNum() << endl;//2

	//海格加入了
	Student* pHagrid = new Student("Hagrid");
	cout << Student::GetAllStudentNum() << endl;//3

	//當物件還存在的時候
	//也可以使用物件來取靜態變數值
	cout << pTom->GetAllStudentNum() << endl;//3
	cout << pMyrtle->GetAllStudentNum() << endl;//3
	cout << pHagrid->GetAllStudentNum() << endl;//3
	//這些結果都會跟 Student::GetAllStudentNum() 一樣
	//就是因為靜態變數是所有物件共有的資料,所以用哪個物件去取都一樣
	
	delete pMyrtle;	//麥朵死掉了
	cout << Student::GetAllStudentNum() << endl;//2

	delete pHagrid;	//海格被開除了
	cout << Student::GetAllStudentNum() << endl;//1

	delete pTom;	//湯姆後來也走了
	cout << Student::GetAllStudentNum() << endl;//0

	system("pause");
	return 0;
}

執行結果

0
1
2
3
3
3
3
2
1
0

小範例2
https://husking-studio.com/cpp-static-simple-example02/

回上一篇:C++ 的 static -靜態變數與函式詳細說明
https://husking-studio.com/cpp-static/

.

在〈C++ 的 static -靜態變數與函式簡單範例1〉中有 2 則留言

    1. 直接在解/建構式裡 m_nAllStudentNum++ 和 m_nAllStudentNum– 當然也是可以。

      文章裡的寫法是我個人的寫程式習慣:
      1.盡量使用靜態函式去獨立處理靜態變數。所以我不會在解/建構式或一般函式直接 m_nAllStudentNum++。
      2.呼叫靜態函式的時候,前面要加上 ClassName::,例如 Student::AddAllStudentNum(); 。

      我的這兩個習慣,是為了增加可讀性,一眼掃過程式碼的時候,能一眼知道這個函式或變數是靜態的,除了能讓我不會跟一般變數產生混淆,也讓我更小心靜態變數的處理。
      不然靜態變數在一般函式被誤用了的話,全部的物件都會被改的,以前在公司的大型專案裡就是出過這種bug,別人出的。後來我為了避免這種情況,才有了這2個處理靜態變數的寫程式習慣。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *