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

C++ 本身没有内置的 Delegate(委托) 类型(不像 C#),但可以通过函数对象(std::function)、可调用对象(lambda、函数指针、绑定对象)和类型擦除等机制,模拟出**类型安全、可复制、支持多播(multicast)的委托行为**。下面是一个轻量、实用、可运行的 C++ 委托实现示例,支持单播与简单多播,不依赖第三方库。
1. 基础单播委托(Function Wrapper)
最常用且推荐的方式是使用 std::function 封装任意可调用对象,它本身就是一种“泛型委托”:
#include <functional>
#include <iostream>
<p>// 定义委托类型:接受 int,返回 void
using IntHandler = std::function<void(int)>;</p><p>void OnValueChanged(int value) {
std::cout << "Value changed to: " << value << '\n';
}</p><p>int main() {
IntHandler handler = OnValueChanged;
handler(42); // 输出:Value changed to: 42</p><pre class="brush:php;toolbar:false;">// 也可绑定 lambda 或成员函数
handler = [](int x) { std::cout << "[Lambda] Got: " << x << '\n'; };
handler(100);}
2. 手写轻量 Delegate 类(支持成员函数)
若需更明确的委托语义(如判空、重载 =、显式调用语法),可封装一个简易 Delegate 模板类。以下支持普通函数、lambda 和非静态成员函数(通过对象指针 + 成员函数指针):
#include <functional>
#include <memory>
<p>template<typename Signature>
class Delegate;</p><p>template<typename R, typename... Args>
class Delegate<R(Args...)> {
std::function<R(Args...)> fn_;</p><p>public:
Delegate() = default;
Delegate(std::nullptr<em>t) {}
Delegate(const std::function<R(Args...)>& f) : fn</em>(f) {}</p><pre class="brush:php;toolbar:false;">template<typename F>
Delegate(F&& f) : fn_(std::forward<F>(f)) {}
// 支持 obj->method 绑定(需传入对象指针)
template<typename T, typename M>
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<bool>(fn_); }
R operator()(Args... args) const { return fn_(std::forward<Args>(args)...); }};
立即学习“C++免费学习笔记(深入)”;
// 使用示例 struct Counter { int value = 0; void increment(int by) { value += by; } };
int main() {
Counter c;
Delegate 多播委托 = 可添加/移除多个监听器,调用时依次执行。用 }; 立即学习“C++免费学习笔记(深入)”; // 示例:事件通知
int main() {
MulticastDelegate }
3. 简易多播委托(MulticastDelegate)
std::vector<:function></:function> 实现最直观:#include <vector>
#include <functional>
#include <algorithm>
<p>template<typename Signature>
class MulticastDelegate;</p><p>template<typename R, typename... Args>
class MulticastDelegate<R(Args...)> {
std::vector<std::function<R(Args...)>> handlers_;</p><p>public:
void add(const std::function<R(Args...)>& fn) {
if (fn) handlers_.push_back(fn);
}</p><pre class="brush:php;toolbar:false;">void remove(const std::function<R(Args...)>& 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>(args)...);
}
}
// 重载 () 直接调用
void operator()(Args... args) const { invoke(std::forward<Args>(args)...); }onChanged(123); // 同时触发两个回调
4. 注意事项与建议
&c)在委托调用前未被销毁;建议配合 std::shared_ptr 或 weak_ptr 防悬挂指针。std::function 有小开销(类型擦除 + 可能堆分配),高频调用场景可用函数指针 + void* 手动绑定(但丧失类型安全)。











