複習上一篇: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/
.
想問一下 既然任何物件都可以改靜態成員的值
造成bug的機率上升,那為啥還要宣告成static的變數或是函式?
有什麼原因嗎? 在看code老是看到忽然出現static
但卻不知道原因… 謝謝
這就要提到物件導向的概念了,在物件導向的概念裡,萬物皆為物件,所以不會有全域變數,那大家共用的資料要怎麼辦?就是使用物件裡的靜態變數。那你說會修改到,就宣告成 private 然後不要給它寫 set 函式或是直接宣告成 const 就不會改到了,這會考驗到程式設計師封裝物件的功力。純物件導向的程式語言,比方說 Java 和 C#,就是這樣處理的。
因為不知道你是使用哪種語言,C++ 的話,因為兼容 C 語言,而 C 語言有全域變數,還有全域函式,然後就造成全域變數也有 static,全域函式也有 static,跟 C++ 語法混在一起就會看不懂,而 C 語言的 static 其實有其他的涵義,但因為我學了物件導向之後就不使用全域變數和全域函式,所以沒深究也不使用。
如果我想到什麼好例子的話,再針對您的問題寫一篇文章,到時再 mail 通知您。..不一定會寫喔,如果您還有其他問題,可以 mail 給我。