答案:通過模板和std::function實現(xiàn)通用觀察者模式,使用Signal模板類管理回調(diào)函數(shù),支持多種事件類型和任意可調(diào)用對象,實現(xiàn)解耦和靈活注冊與通知機(jī)制。
在C++中實現(xiàn)一個通用的觀察者模式,關(guān)鍵是解耦觀察者和被觀察對象,同時支持多種事件類型和回調(diào)方式。可以通過模板和函數(shù)對象(如std::function)來實現(xiàn)靈活性和復(fù)用性。
觀察者模式包含兩個核心角色:Subject(被觀察者)和Observer(觀察者)。為了通用性,我們不使用傳統(tǒng)的虛函數(shù)接口,而是用回調(diào)機(jī)制。
核心思路:
下面是一個可復(fù)用的通用Subject模板:
立即學(xué)習(xí)“C++免費學(xué)習(xí)筆記(深入)”;
#include <functional> #include <vector> #include <algorithm> template <typename... Args> class Signal { private: using Callback = std::function<void(Args...)>; std::vector<Callback> observers; public: // 注冊觀察者 void connect(Callback callback) { observers.push_back(std::move(callback)); } // 發(fā)送通知 void notify(Args... args) { for (auto& cb : observers) { cb(args...); } } // 移除所有觀察者(可選) void disconnect_all() { observers.clear(); } };
假設(shè)我們要監(jiān)控溫度變化:
#include <iostream> int main() { Signal<double> temperature_changed; // 觀察者1:打印日志 temperature_changed.connect([](double temp) { std::cout << "Log: Temperature is now " << temp << "°C\n"; }); // 觀察者2:觸發(fā)警報 temperature_changed.connect([](double temp) { if (temp > 100) { std::cout << "Alert: High temperature detected!\n"; } }); // 模擬溫度變化 temperature_changed.notify(25.5); // 正常輸出 temperature_changed.notify(105.0); // 觸發(fā)警報 return 0; }
上面的實現(xiàn)無法單獨移除某個觀察者??梢苑祷匾粋€“連接句柄”用于取消訂閱:
一種簡單方法是返回一個lambda,調(diào)用它即從列表中刪除對應(yīng)回調(diào)。更復(fù)雜但高效的方式是使用連接管理器或信號槽庫(如Boost.Signals2)的思想。
基本上就這些。這個通用實現(xiàn)輕量、靈活,適用于大多數(shù)場景,不依賴?yán)^承,支持任意可調(diào)用對象(函數(shù)指針、lambda、bind結(jié)果等),能處理多種參數(shù)類型。
以上就是c++++如何實現(xiàn)一個通用的觀察者模式 _c++觀察者模式實現(xiàn)方法的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
c++怎么學(xué)習(xí)?c++怎么入門?c++在哪學(xué)?c++怎么學(xué)才快?不用擔(dān)心,這里為大家提供了c++速學(xué)教程(入門到精通),有需要的小伙伴保存下載就能學(xué)習(xí)啦!
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號