首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ 模擬 C# event 關鍵字:模板實作、運算子多載與委派機制對比

     編輯:C++ 入門

背景動機

C# 內建 event 關鍵字提供發布-訂閱模式,C++ 無對應語言特性,但可透過模板 + 運算子多載模擬核心功能。

核心 event 模板實作


template 
class event {
private:
    Handler handler_;
protected:
    // 可覆寫的 add/remove 存取器 (對應 C# event accessors)
    virtual void add(const Handler& h) { handler_ = h; }
    virtual void remove(const Handler& h) { if (h == handler_) handler_ = nullptr; }
public:
    event() : handler_(nullptr) {}
    
    // += 訂閱
    event& operator+=(const Handler& h) { add(h); return *this; }
    // -= 退訂
    event& operator-=(const Handler& h) { remove(h); return *this; }
    // 隱式轉換為 Handler (對應 C# 直接呼叫 event)
    operator Handler() const { return handler_; }
};

定義事件處理函數簽名


// 使用 typedef 定義委派型別 (對應 C# delegate)
using EventHandler = void(*)();

// 含參數版本
using EventHandlerEx = void(*)(int, const std::string&);

發布者類別實作


class MyClass {
public:
    MyClass() = default;
    
    // 宣告事件 (對應 C#: public event EventHandler AEvent;)
    event AEvent;
    
    // 觸發事件
    void FireEvent() {
        if (AEvent != nullptr) {
            // C++ 需要顯式轉換呼叫
            static_cast(AEvent)();
        }
    }
};

用戶端訂閱與使用


void MyEventHandler() {
    std::printf("This is an event!\n");
}

int main() {
    MyClass obj;
    
    obj.AEvent += MyEventHandler;  // 訂閱
    obj.FireEvent();               // 觸發 -> 輸出事件訊息
    
    obj.AEvent -= MyEventHandler;  // 退訂
    obj.FireEvent();               // 無輸出
    
    return 0;
}

C# vs C++ 對比表

擴展:支援多播 (多個訂閱者)


template 
class multicast_event {
    std::vector handlers_;
public:
    multicast_event& operator+=(const Handler& h) {
        handlers_.push_back(h);
        return *this;
    }
    
    multicast_event& operator-=(const Handler& h) {
        handlers_.erase(std::remove(handlers_.begin(), handlers_.end(), h), handlers_.end());
        return *this;
    }
    
    template 
    void operator()(Args&&... args) const {
        for (const auto& h : handlers_)
            h(std::forward(args)...);
    }
};

// 使用方式
multicast_event OnValueChanged;
OnValueChanged += [](int v) { std::cout << "A: " << v << "\n"; };
OnValueChanged += [](int v) { std::cout << "B: " << v << "\n"; };
OnValueChanged(42);  // 兩個處理器都被呼叫

現代 C++ 替代方案

  • Boost.Signals2:執行緒安全、自動連線管理、完整多播支援
  • std::function + std::vector:簡單輕量手寫版
  • 觀察者模式介面:IObserver 虛擬介面,適合跨 DLL 邊界
  • C++26 標準化提案:std::observable 正在提案中

核心洞見

C# delegate ≈ C++ 函數指標/物件,event ≈ 模板封裝 + operator+=/-= + 隱式轉換。C# 將易錯的手動管理 (記憶體、多執行緒、生命週期) 封裝進編譯器/執行時,讓開發者專注業務邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性C# eventC++ 模擬版
語言支援關鍵字原生支援模板類別 + 運算子多載
宣告語法event EventHandler E;event E;
訂閱/退訂+= / -=operator+= / operator-=
觸發呼叫E() 直接呼叫static_cast(E)() 需轉換
多播支援內建多播委派單一處理器 (需自行擴展)
add/remove 存取器add/remove 關鍵字虛擬函式 add/remove
型別安全編譯期完整檢查模板參數提供檢查