普通成員函數可以訪問所有成員(包括成員變量和成員函數),靜態成員函數只能訪問靜態成員
編譯器在編譯一個普通成員函數時,會隱式地增加一個形參 this,並把當前對象的地址賦值給 this,所以普通成員函數只能在創建對象后通過對象來調用,因為它需要當前對象的地址。而靜態成員函數可以通過類來直接調用,編譯器不會為它增加形參 this,它不需要當前對象的地址,所以不管有沒有創建對象,都可以調用靜態成員函數
普通成員變量占用對象的內存,靜態成員函數沒有 this 指針,不知道指向哪個對象,無法訪問對象的成員變量,也就是說靜態成員函數不能訪問普通成員變量,只能訪問靜態成員變量
普通成員函數必須通過對象才能調用,而靜態成員函數沒有 this 指針,無法在函數體內部訪問某個對象,所以不能調用普通成員函數,只能調用靜態成員函數
靜態成員函數與普通成員函數的根本區別在於:普通成員函數有 this 指針,可以訪問類中的任意成員;而靜態成員函數沒有 this 指針,只能訪問靜態成員(包括靜態成員變量和靜態成員函數)
#include <iostream> #include <string> using namespace std; class Student { public: Student(const string& name, int age, float score); void show(); public: //聲明靜態成員函數 static int getTotal(); static float getPoints(); private: static int m_total; //總人數 static float m_points; //總成績 private: string m_name; int m_age; float m_score; }; int Student::m_total = 0; float Student::m_points = 0.0; Student::Student(const string& name, int age, float score) : m_name(name), m_age(age), m_score(score) { m_total++; m_points += score; } void Student::show() { 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(); int total = Student::getTotal(); float points = Student::getPoints(); cout << "當前共有" << total << "名學生,總成績是" << points << ",平均分是" << points / total << endl; return 0; }
靜態成員函數可以通過類來調用(一般都是這樣做),也可以通過對象來調用