面向物件程式設計中,物件極少孤立存在。建立物件間的關聯與訊息連結是核心任務。當「事件物件」發生狀態變化時,需通知「回調物件」執行處理,這在 C++ 中對應調用回調物件的成員函數。傳統做法需手動傳遞物件指標,缺乏通用性。本文提出一套系統化的 CallBack 類別,將「事件發生 → 註冊回調 → 執行處理」抽象封裝,透過繼承即可輕鬆獲得物件間訊息連結機制。
支援三種回調函數類型:
class EventRecord {
char *eventName; // 事件名稱
CallBack *pointerToCBO; // 回調物件指標
union {
CallBackFunction pointerToCBF; // 成員函數指標
CallBackStaticFunction pointerToCBSF; // 靜態/一般函數指標
};
// 建構子、比較運算子、清理函數等...
};
CallBack 類別維護一個動態擴展的事件記錄表 callBackList,提供註冊、移除、觸發三大核心操作。
// 註冊物件成員函數
void CallBack::AddCallBack(char *event, CallBackFunction cbf, CallBack *p);
// 註冊靜態成員函數或一般函數
void CallBack::AddCallBack(char *event, CallBackStaticFunction cbsf);
使用範例:
// 成員函數指標傳遞格式
(CallBackFunction)&SomeObject::MemberFunctionName
// 靜態成員函數指標
(CallBackStaticFunction)&SomeObject::StaticFunctionName
// 一般函數直接傳函數名
void CallBack::CallCallBack(char *ename, CallData calldata = NULL);
遍歷回調表,查找匹配事件名的所有記錄並執行對應函數。calldata(實為 void*)用於傳遞事件相關資料。
void RemoveCallBack(char *event, CallBackFunction cbf, CallBack *p); // 移除特定成員函數
void RemoveCallBack(char *event, CallBackStaticFunction cbsf); // 移除特定靜態/一般函數
void RemoveCallBack(char *event); // 移除該事件所有回調
CallBack 類別CallCallBack 觸發通知class Speaker : public CallBack {
int volume;
public:
void IncreaseVolume(int v) {
volume += v;
if (volume > 20) { // 觸發「音量大於20」事件
CallCallBack("音量改變了");
CallCallBack("音量大於20", &volume);
}
}
void DecreaseVolume(int v) {
volume -= v;
if (volume < 5) { // 觸發「音量小於5」事件
CallCallBack("音量改變了");
CallCallBack("音量小於5", &volume);
}
}
};
class Ear : public CallBack {
public:
static void Response(CallData d) { cout << "音量改變了." << endl; }
void HighVoiceResponse(CallData d) {
cout << "喂!太吵了!現在音量:" << *((int*)d) << endl;
}
void LowVoiceResponse(CallData d) {
cout << "啊!我聽不清了。現在音量:" << *((int*)d) << endl;
}
};
void main() {
Speaker s(10); Ear e;
s.AddCallBack("音量大於20", (CallBackFunction)&Ear::HighVoiceResponse, &e);
s.AddCallBack("音量小於5", (CallBackFunction)&Ear::LowVoiceResponse, &e);
s.AddCallBack("音量改變了", (CallBackStaticFunction)&Ear::Response);
s.IncreaseVolume(12); // 音量變 22,觸發兩事件
s.DecreaseVolume(20); // 音量變 2,觸發兩事件
}
音量改變了.
喂!太吵了!現在音量是:22
音量改變了.
啊!我聽不清了。現在音量是:2
文章附帶完整的 callback.h 與 callback.cpp,包含:
EventRecord 類別:事件記錄節點管理、比較運算子、記憶體管理CallBack 類別:動態陣列擴展、註冊/移除/觸發邏輯、複製建構子與賦值運算子透過 CallBack 類別,物件間訊息連結變得簡單優雅。該設計將事件驅動機制封裝為可重用基類,大幅減少樣板程式碼,適合各類 C++ 事件驅動應用開發。