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

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

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

這邊舉個簡單的例子。

一個班級裡的黑板,所有學生一定都是看到一樣的內容吧,所以「黑板上的內容」對每個學生來說應該算是「共用資料」吧!不管是誰改了黑板上的字,大家都會看到一樣的內容。而且不只是學生,甚至老師、路人,都是看到一樣的內容。

所以寫一個 Student 的類別,把黑板設定成靜態成員變數。

class Student
{
private:
	string m_strName;	//學生名字
	static string m_strBlackboard;	//黑板內容(靜態成員變數)
public:
	Student(string strName) { m_strName = strName; }
public:
	string GetName() { return m_strName; };
	static void WriteBlackboard(std::string strText) { m_strBlackboard = strText; }
	static string SeeBlackboard() { return m_strBlackboard; }
};

string Student::m_strBlackboard = "";	//初始化,一開始黑板上什麼都沒寫

現在班上沒有學生,但任何東西都可以看黑板內容,就是空空的。任何東西是什麼?可能是教授、蒼蠅,總之所有有眼睛的生物看到的黑板就是什麼都沒寫。

int main()
{
	cout << Student::SeeBlackboard() << endl;

	system("pause");
	return 0;
}

執行結果


哈利和榮恩來了,黑板上還是什麼都沒寫。所以哈利和榮恩看到一片空白, 任何東西看到的黑板都是一片空白。

int main()
{
	Student* pHarry = new Student("Harry");
	Student* pRon = new Student("Ron");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	delete pRon;
	delete pHarry;
	system("pause");
	return 0;
}

執行結果




然後哈利在黑板寫了個咒語,所以哈利、榮恩及其他所有有眼睛的任何東西,都會看到哈利寫的咒語。

int main()
{
	Student* pHarry = new Student("Harry");
	Student* pRon = new Student("Ron");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	pHarry->WriteBlackboard("Lumos");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	delete pRon;
	delete pHarry;

	system("pause");
	return 0;
}

執行結果




Lumos
Lumos
Lumos

接下來不知道是誰又寫了個新咒語,真的不知道是誰啊, 太可怕了, 眾目睽睽之下黑板上又改了字了,所以哈利、榮恩及其他所有有眼睛的任何東西都看到了黑板上的字改變了。

int main()
{
	Student* pHarry = new Student("Harry");
	Student* pRon = new Student("Ron");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	pHarry->WriteBlackboard("Lumos");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	Student::WriteBlackboard("Riddikulus");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	delete pRon;
	delete pHarry;

	system("pause");
	return 0;
}

執行結果




Lumos
Lumos
Lumos
Riddikulus
Riddikulus
Riddikulus

最後哈利和榮恩走了,黑板上還是留著最後的字。

int main()
{
	Student* pHarry = new Student("Harry");
	Student* pRon = new Student("Ron");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	pHarry->WriteBlackboard("Lumos");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	Student::WriteBlackboard("Riddikulus");

	cout << pHarry->SeeBlackboard() << endl;
	cout << pRon->SeeBlackboard() << endl;
	cout << Student::SeeBlackboard() << endl;

	delete pRon;
	delete pHarry;

	cout << Student::SeeBlackboard() << endl;

	system("pause");
	return 0;
}

執行結果




Lumos
Lumos
Lumos
Riddikulus
Riddikulus
Riddikulus
Riddikulus

這個例子也可以發現,取值是沒有什麼問題,但是改值就要很注意了,每個物件都可以改,甚至外人也可以改,而且只要改了,所有物件都會影響到,所以在改靜態成員變數時,一定要非常小心。

進階實驗
https://husking-studio.com/cpp-static-experiment/

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

.

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

  1. 想問一下 既然任何物件都可以改靜態成員的值
    造成bug的機率上升,那為啥還要宣告成static的變數或是函式?

    有什麼原因嗎? 在看code老是看到忽然出現static
    但卻不知道原因… 謝謝

    1. 這就要提到物件導向的概念了,在物件導向的概念裡,萬物皆為物件,所以不會有全域變數,那大家共用的資料要怎麼辦?就是使用物件裡的靜態變數。那你說會修改到,就宣告成 private 然後不要給它寫 set 函式或是直接宣告成 const 就不會改到了,這會考驗到程式設計師封裝物件的功力。純物件導向的程式語言,比方說 Java 和 C#,就是這樣處理的。

      因為不知道你是使用哪種語言,C++ 的話,因為兼容 C 語言,而 C 語言有全域變數,還有全域函式,然後就造成全域變數也有 static,全域函式也有 static,跟 C++ 語法混在一起就會看不懂,而 C 語言的 static 其實有其他的涵義,但因為我學了物件導向之後就不使用全域變數和全域函式,所以沒深究也不使用。

      如果我想到什麼好例子的話,再針對您的問題寫一篇文章,到時再 mail 通知您。..不一定會寫喔,如果您還有其他問題,可以 mail 給我。

發佈留言

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