C++多层模板类间的数据传递方案咨询
类层级间数据传递的可行方案补充
示例代码
struct InteractWithUser{ void showInfo(){ printf("Connected clients: %d\n", x); } int x; }; struct Worker{ InteractWithUser ui; }; struct TCPServer{ int connected_clients; Worker w; bool processLoop(); InteractWithUser &getUI(){ return w.ui; } }; int main(){ TCPServer srv; while(srv.processLoop()){ // 除了虚函数,我想不到别的办法了 srv.getUI().x = srv.connected_clients; } }
需求与现有方案
我需要在类之间传递数据(比如示例中的srv.connected_clients),但TCPServer和InteractWithUser之间隔了多个模板类,难以确定确切类型。目前想到三种方法:
- 在服务器循环内执行
srv.getUI().x = srv.connected_clients;,但循环内手动赋值的方式不够理想。 - 在InteractWithUser中存储
srv.connected_clients的指针或引用,但可能引发生命周期等问题。 - 使用抽象类与虚函数。
补充可行方案
- 观察者模式:将TCPServer设为被观察者,InteractWithUser作为观察者。当
connected_clients数值变化时,TCPServer主动通知所有订阅的观察者更新数据。这种方式无需循环内手动赋值,避免了直接持有引用/指针的风险,且通过抽象观察者接口能适配模板类的类型不确定性。 - 依赖注入:给InteractWithUser注入一个抽象的
ClientCountProvider接口(而非直接依赖TCPServer),该接口提供获取客户端数量的方法。InteractWithUser仅依赖抽象接口,不关心具体实现类,完美适配模板类场景下的类型模糊问题。 - 函数对象/
std::function:在InteractWithUser中存储一个可调用对象,比如std::function<int()> client_count_getter。初始化时将获取connected_clients的逻辑绑定进去(例如[&srv](){ return srv.connected_clients; }),既避免了直接持有对象引用,又能灵活获取数据,适配模板类场景。 - 事件总线:引入事件总线中间层,TCPServer在
connected_clients变化时发送事件,InteractWithUser订阅该事件并更新自身数据。这种方式彻底解耦两个类,适合复杂层级和模板类场景,唯一缺点是增加了中间层的复杂度。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

