普通成員函數隱含 this 指標,故需透過物件呼叫;靜態成員函數無 this 指標,屬於類別而非具體物件,可直接透過類別名呼叫(ClassName::func()),亦可透過物件呼叫(不推薦)。
this 不知道操作哪個物件的資料。本質上,靜態成員函數編譯後等同於全域函數,只是被置於類別作用域內,享有類別的存取權限控制(private/protected/public)。
class Student {
public:
static int getTotal(); // 宣告加 static
static float getPoints();
private:
static int m_total; // 靜態成員變數
static float m_points;
};
// 定義時「不加」static
int Student::getTotal() { return m_total; }
float Student::getPoints() { return m_points; }
#include <iostream>
using namespace std;
class Student {
public:
Student(const char* name, int age, float score);
void show() const;
static int getTotal(); // 取得總人數
static float getPoints(); // 取得總分
private:
static int m_total;
static float m_points;
const char* m_name;
int m_age;
float m_score;
};
// 靜態成員變數類外初始化
int Student::m_total = 0;
float Student::m_points = 0.0f;
Student::Student(const char* name, int age, float score)
: m_name(name), m_age(age), m_score(score) {
++m_total;
m_points += score;
}
void Student::show() const {
cout << m_name << " 年齡 " << m_age << " 成績 " << m_score << endl;
}
int Student::getTotal() { return m_total; }
float Student::getPoints() { return m_points; }
int main() {
(new Student("小明", 15, 90.6))->show();
(new Student("李磊", 16, 80.5))->show();
(new Student("張華", 16, 99.0))->show();
(new Student("王康", 14, 60.8))->show();
cout << "當前共有 " << Student::getTotal()
<< " 名學生,總成績 " << Student::getPoints()
<< ",平均分 " << Student::getPoints() / Student::getTotal() << endl;
return 0;
}
static Student* create(...) 封裝建構邏輯。注意:雖然 getTotal()、getPoints() 也可宣告為非靜態,但加上 static 語義更精確——它們不依賴特定物件,屬於類別層級操作。
this → 編譯錯誤。m_name 等非靜態成員 → 編譯錯誤。static 關鍵字 → 語法錯誤(僅宣告需加)。靜態成員函數是「類別層級的服務」,不綁定具體物件,專職管理共享狀態或提供無狀態工具。善用它能讓類別介面更清晰、封裝更完整。