C++ 无内置委托类型,但可用 std::function、lambda、bind 等模拟类型安全可复制的单播与多播委托;示例涵盖基础封装、成员函数支持及多播实现,并强调生命周期管理与性能权衡。

C++ 本身没有内置的 Delegate(委托) 类型(不像 C#),但可以通过函数对象(std::function)、可调用对象(lambda、函数指针、绑定对象)和类型擦除等机制,模拟出 ** 类型安全、可复制、支持多播(multicast)的委托行为 **。下面是一个轻量、实用、可运行的 C++ 委托实现示例,支持单播与简单多播,不依赖第三方库。
1. 基础单播委托(Function Wrapper)
最常用且推荐的方式是使用 std::function 封装任意可调用对象,它本身就是一种“泛型委托”:
#include #include // 定义委托类型:接受 int,返回 void using IntHandler = std::function;
void OnValueChanged(int value) {std::cout << "Value changed to:" << value << 'n';}
int main() { IntHandler handler = OnValueChanged; handler(42); // 输出:Value changed to: 42
// 也可绑定 lambda 或成员函数 handler = [](int x) {std::cout << "[Lambda] Got:" <
}
2. 手写轻量 Delegate 类(支持成员函数)
若需更明确的委托语义(如判空、重载 =、显式调用语法),可封装一个简易 Delegate 模板类。以下支持普通函数、lambda 和非静态成员函数(通过对象指针 + 成员函数指针):
#include #include template class Delegate;
template class Delegate {std::function fn_;
public: Delegate() = default; Delegate(std::nullptrt) {} Delegate(const std::function& f) : fn (f) {}
template Delegate(F&& f) : fn_(std::forward(f)) {} // 支持 obj->method 绑定(需传入对象指针)template Delegate(T* obj, M method) : fn_(std::bind(method, obj, std::placeholders::_1……)) {} bool operator==(std::nullptr_t) const {return !fn_;} explicit operator bool() const { return static_cast(fn_); } R operator()(Args…… args) const {return fn_(std::forward(args)……); }
};
立即学习 “C++ 免费学习笔记(深入)”;
// 使用示例 struct Counter {int value = 0; void increment(int by) {value += by;} };
int main() { Counter c; Delegate del(&c, &Counter::increment); del(5); std::cout
3. 简易多播委托(MulticastDelegate)
多播委托 = 可添加 / 移除多个监听器,调用时依次执行。用 std::vector<:function> 实现最直观:
#include #include #include template class MulticastDelegate;
template class MulticastDelegate {std::vector> handlers_;
public: void add(const std::function& fn) {if (fn) handlers_.push_back(fn); }
void remove(const std::function& fn) {handlers_.erase( std::remove_if(handlers_.begin(), handlers_.end(), [&fn](const auto& h) {return h.target_type() == fn.target_type();}), handlers_.end()); } void invoke(Args…… args) const {for (const auto& h : handlers_) {h(std::forward(args)……); } } // 重载 () 直接调用 void operator()(Args…… args) const {invoke(std::forward(args)……); }
};
立即学习 “C++ 免费学习笔记(深入)”;
// 示例:事件通知 int main() { MulticastDelegate onChanged; onChanged.add([](int v) {std::cout
onChanged(123); // 同时触发两个回调
}
4. 注意事项与建议
- 生命周期管理是关键 :绑定成员函数时,确保对象(如
&c)在委托调用前未被销毁;建议配合 std::shared_ptr 或 weak_ptr 防悬挂指针。
- 性能考虑 :
std::function 有小开销(类型擦除 + 可能堆分配),高频调用场景可用函数指针 + void* 手动绑定(但丧失类型安全)。
- 不推荐手动实现“C# 式完整委托系统”:C++ 生态已有成熟方案,如 libdelegate、ENTT 的 signal,或 Boost.Signals2。
- 现代替代思路 :对事件驱动逻辑,优先考虑基于回调的观察者模式、信号槽(如 Qt)或协程 +channel(C++20+)。