靜態成員函數沒有 this 指針。這是其所有特性的根源:無法訪問非靜態成員、地址類型為普通函數指針、不可聲明為 virtual/const/volatile、可通過類名直接調用。
class Widget {
public:
static void staticFunc() {}
void memberFunc() {}
};
void (*pStatic)() = &Widget::staticFunc; // 普通函數指針
void (Widget::*pMember)() = &Widget::memberFunc; // 成員函數指針 (需對象調用)
// pStatic() 直接調用;pMember 需 (obj.*pMember)()
用途:作為 C 風格回調函數、線程入口函數 (如 pthread_create、CreateThread)、信號處理函數。
class Counter {
static int s_count;
int m_count;
public:
static void increment() {
s_count++; // OK
// m_count++; // 編譯錯誤:無 this,不知操作哪個對象的 m_count
}
};
class Base {
// virtual static void foo(); // 錯誤:虛函數需 this 實現多態分發
// static void bar() const; // 錯誤:const 修飾 this,靜態函數無 this
// static void baz() volatile; // 錯誤:同理
};
class Math {
public:
static int add(int a, int b) { return a + b; }
};
int main() {
Math::add(1, 2); // 直接通過類名調用
// Math m; m.add(1,2); // 也合法,但語義誤導 (看起來像調用對象方法)
}
class Database {
static std::unique_ptr instance;
Database() {} // 私有構造
public:
static Database& getInstance() {
if (!instance) instance = std::make_unique();
return *instance;
}
static void destroy() { instance.reset(); } // 受控銷毀
};
class StringUtils {
public:
static std::string trim(const std::string& s);
static std::vector split(const std::string& s, char delim);
// 無狀態,純工具,歸類於 StringUtils 下
};
class ThreadWorker {
int id_;
public:
ThreadWorker(int id) : id_(id) {}
void run() { /* 線程邏輯 */ }
// 靜態包裝器,轉發到成員函數
static void* threadEntry(void* arg) {
static_cast(arg)->run();
return nullptr;
}
};
// 使用
ThreadWorker worker(1);
pthread_t tid;
pthread_create(&tid, nullptr, &ThreadWorker::threadEntry, &worker);
std::function + std::bind/Lambda:替代靜態函數指針回調,類型安全、支持捕獲上下文。std::jthread (C++20) / std::thread:直接接受可調用對象,無需靜態包裝器。靜態成員函數是「無 this 的類作用域函數」。核心價值在於:提供類級操作入口 (工廠、單例、工具)、兼容 C 风格回調 (普通函數指針地址)。理解其「無 this」本質,能正確判斷訪問權限、地址類型、CV 資格限制。現代 C++ 多用自由函數 + 命名空間替代工具類,用標準庫線程/可調用對象替代靜態包裝器。