1. 背景:

在大型的工程项目C++ 工程中, C++ 回调使用的非常多。而回调又很多种书写的形式,让我们来总结一些,并且用回调写一个观察者模式来作为练习。

2. 8 种常见回调。

2.1 C 风格函数指针 (C-style function pointer)

用法:

// 定义函数指针类型:接受 int 返回 void
using CallbackFunc = void (*)(int);

// 接收函数指针作为回调的函数
void process_with_func_ptr(int val, CallbackFunc cb)
{
    std::cout << "process_with_func_ptr : val" << val << std::endl;
    int ret = val * 20;
    cb(ret);
}

// 一个符合 CallbackFunc 签名的普通函数
void my_c_func(int x)
{
    std::cout << " [func_ptr] result = " << x << "\n";
}

调用:

    // ---- 1. 函数指针 ----
    std::cout << "[1] Function pointer:";
    process_with_func_ptr(10, my_c_func); // 传入普通函数名

//    最传统的回调方式,参数类型完全由函数签名决定。

//    优点:零开销;缺点:无法捕获状态,类型擦除能力弱。

2.2 std::function(标准函数包装器)

void process_with_std_func(int val, std::function<void(int)> cb)
{
    cb(val * 3);
}
    process_with_std_func(10, [](int x) { // 直接传 lambda
        std::cout << " result = " << x << "\n";
    });

//    可存储可调用对象(函数、lambda、函子、bind 表达式等)。
//    优点:类型擦除,灵活;缺点:有轻微运行时开销(堆分配可能)。

2.3  函子 / 函数对象 (Functor / Function Object)

struct MultiplyPrinter
{
    int factor; // 内部状态:乘数因子

    explicit MultiplyPrinter(int f) : factor(f) {}

    // 重载 () 使其成为可调用对象
    void operator()(int val) const
    {
        std::cout << " [functor]  result = " << val * factor << "\n";
    }
};
    process_with_std_func(10, MultiplyPrinter(4)); // 传入临时函子对象

//    重载 operator() 的类,可保存内部状态。

//    优点:可以携带配置/数据;缺点:需要额外定义类。

2.4 Lambda 表达式 (Lambda expression)

auto make_lambda_cb(int multiplier)
{
    // [multiplier] 按值捕获外部变量
    return [multiplier](int val)
    {
        std::cout << " [lambda]   result = " << val * multiplier << "\n";
    };
}
    auto cb = make_lambda_cb(5); // 工厂函数返回 lambda
    process_with_std_func(10, cb);

//    C++11 引入的匿名闭包,可捕获外部变量。
//    优点:语法简洁,捕获灵活(值/引用/move);现代 C++ 首选。

2.5 成员函数回调 (Member function callback)

class Handler
{
public:
    // 非静态成员函数:隐式含 this 指针
    void on_event(int val)
    {
        std::cout << " [member]   result = " << val * 5 << "\n";
    }

    // 静态成员函数:不含 this,可当普通函数指针用
    static void static_on_event(int val)
    {
        std::cout << " [static]   result = " << val * 6 << "\n";
    }
};
    Handler h;
    // 方式一:std::bind 绑定 this 和占位符
    process_with_std_func(10, std::bind(&Handler::on_event, &h, std::placeholders::_1));
    // 方式二:用 lambda 包装(更推荐,更清晰)
    process_with_std_func(10, [&h](int v)
                          { h.on_event(v); });

//    类的非静态成员函数不能直接作为回调,需要用 bind 或 lambda 包装。
//    静态成员函数可以当作普通函数指针使用。

2.6 模板回调 (Template-based callback)

//    编译期多态,通过模板参数推导出可调用类型。

//    优点:零开销,完全内联;缺点:必须是模板函数,实现暴露在头文件。

template <typename Callable>
void process_template(int val, Callable &&cb)
{
    cb(val * 7);
}
    process_template(10, [](int x)
                     { std::cout << " result = " << x << "\n"; });

2.7 异步回调 (Async callback with std::thread)

void async_work(std::function<void(int)> cb)
{
    // 在新线程中执行回调
    std::thread t([cb]()
                  {
        std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟耗时
        cb(100); });
    t.detach(); // 分离线程,不阻塞主线程
}
    async_work([](int x)
               { std::cout << "     async result = " << x << "\n"; });
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 等异步完成

//    将回调传给另一个线程执行,演示线程安全的基本用法。

//    std::thread 构造后立即启动,调用 detach() 让其后台运行。

2.8 事件系统 (Event system with multiple callbacks)

class EventEmitter
{
    std::vector<std::function<void(int)>> listeners; // 监听器列表

public:
    // 注册一个监听器
    void on(std::function<void(int)> listener)
    {
        listeners.push_back(std::move(listener));
    }

    // 触发事件,通知所有监听器
    void emit(int val)
    {
        for (auto &cb : listeners)
            cb(val);
    }
};
    EventEmitter emitter;
    emitter.on([](int v)
               { std::cout << "     listener1 got " << v << "\n"; });
    emitter.on([](int v)
               { std::cout << "     listener2 got " << v * 2 << "\n"; });
    emitter.emit(10); // 触发事件

2.9 总结:

完整代码:

#include <iostream>
#include <functional>
#include <vector>
#include <thread>
#include <chrono>

// ============================================================
// 1. C 风格函数指针 (C-style function pointer)
//    最传统的回调方式,参数类型完全由函数签名决定。
//    优点:零开销;缺点:无法捕获状态,类型擦除能力弱。
// ============================================================

// 定义函数指针类型:接受 int 返回 void
using CallbackFunc = void (*)(int);

// 接收函数指针作为回调的函数
void process_with_func_ptr(int val, CallbackFunc cb)
{
    std::cout << "process_with_func_ptr : val" << val << std::endl;
    int ret = val * 20;
    cb(ret);
}

// 一个符合 CallbackFunc 签名的普通函数
void my_c_func(int x)
{
    std::cout << " [func_ptr] result = " << x << "\n";
}

// ============================================================
// 2. std::function(标准函数包装器)
//    可存储可调用对象(函数、lambda、函子、bind 表达式等)。
//    优点:类型擦除,灵活;缺点:有轻微运行时开销(堆分配可能)。
// ============================================================
void process_with_std_func(int val, std::function<void(int)> cb)
{
    cb(val * 3);
}

// ============================================================
// 3. 函子 / 函数对象 (Functor / Function Object)
//    重载 operator() 的类,可保存内部状态。
//    优点:可以携带配置/数据;缺点:需要额外定义类。
// ============================================================
struct MultiplyPrinter
{
    int factor; // 内部状态:乘数因子

    explicit MultiplyPrinter(int f) : factor(f) {}

    // 重载 () 使其成为可调用对象
    void operator()(int val) const
    {
        std::cout << " [functor]  result = " << val * factor << "\n";
    }
};

// ============================================================
// 4. Lambda 表达式 (Lambda expression)
//    C++11 引入的匿名闭包,可捕获外部变量。
//    优点:语法简洁,捕获灵活(值/引用/move);现代 C++ 首选。
// ============================================================
auto make_lambda_cb(int multiplier)
{
    // [multiplier] 按值捕获外部变量
    return [multiplier](int val)
    {
        std::cout << " [lambda]   result = " << val * multiplier << "\n";
    };
}

// ============================================================
// 5. 成员函数回调 (Member function callback)
//    类的非静态成员函数不能直接作为回调,需要用 bind 或 lambda 包装。
//    静态成员函数可以当作普通函数指针使用。
// ============================================================
class Handler
{
public:
    // 非静态成员函数:隐式含 this 指针
    void on_event(int val)
    {
        std::cout << " [member]   result = " << val * 5 << "\n";
    }

    // 静态成员函数:不含 this,可当普通函数指针用
    static void static_on_event(int val)
    {
        std::cout << " [static]   result = " << val * 6 << "\n";
    }
};

// ============================================================
// 6. 模板回调 (Template-based callback)
//    编译期多态,通过模板参数推导出可调用类型。
//    优点:零开销,完全内联;缺点:必须是模板函数,实现暴露在头文件。
// ============================================================
template <typename Callable>
void process_template(int val, Callable &&cb)
{
    cb(val * 7);
}

// ============================================================
// 7. 异步回调 (Async callback with std::thread)
//    将回调传给另一个线程执行,演示线程安全的基本用法。
//    std::thread 构造后立即启动,调用 detach() 让其后台运行。
// ============================================================
void async_work(std::function<void(int)> cb)
{
    // 在新线程中执行回调
    std::thread t([cb]()
                  {
        std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟耗时
        cb(100); });
    t.detach(); // 分离线程,不阻塞主线程
}

// ============================================================
// 8. 事件系统 (Event system with multiple callbacks)
//    观察者模式的简化版:支持注册多个监听器,批量通知。
// ============================================================
class EventEmitter
{
    std::vector<std::function<void(int)>> listeners; // 监听器列表

public:
    // 注册一个监听器
    void on(std::function<void(int)> listener)
    {
        listeners.push_back(std::move(listener));
    }

    // 触发事件,通知所有监听器
    void emit(int val)
    {
        for (auto &cb : listeners)
            cb(val);
    }
};

// ============================================================
// 主函数:依次展示每种回调方式
// ============================================================
int main()
{
    std::cout << "=== C++ Callback Demos ===\n\n";

    // ---- 1. 函数指针 ----
    std::cout << "[1] Function pointer:";
    process_with_func_ptr(10, my_c_func); // 传入普通函数名

    
    // ---- 2. std::function ----
    std::cout << "[2] std::function:";
    process_with_std_func(10, [](int x) { // 直接传 lambda
        std::cout << " result = " << x << "\n";
    });

    // ---- 3. 函子 ----
    std::cout << "[3] Functor:";
    process_with_std_func(10, MultiplyPrinter(4)); // 传入临时函子对象

    // ---- 4. Lambda ----
    std::cout << "[4] Lambda:";
    auto cb = make_lambda_cb(5); // 工厂函数返回 lambda
    process_with_std_func(10, cb);

    // ---- 5. 成员函数 ----
    std::cout << "[5] Member function:";
    Handler h;
    // 方式一:std::bind 绑定 this 和占位符
    process_with_std_func(10, std::bind(&Handler::on_event, &h, std::placeholders::_1));
    // 方式二:用 lambda 包装(更推荐,更清晰)
    process_with_std_func(10, [&h](int v)
                          { h.on_event(v); });

    // ---- 6. 模板 ----
    std::cout << "[6] Template:";
    process_template(10, [](int x)
                     { std::cout << " result = " << x << "\n"; });

    // ---- 7. 异步回调 ----
    std::cout << "[7] Async (thread): waiting...\n";
    async_work([](int x)
               { std::cout << "     async result = " << x << "\n"; });
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 等异步完成

    // ---- 8. 事件系统 ----
    std::cout << "[8] Event system:\n";
    EventEmitter emitter;
    emitter.on([](int v)
               { std::cout << "     listener1 got " << v << "\n"; });
    emitter.on([](int v)
               { std::cout << "     listener2 got " << v * 2 << "\n"; });
    emitter.emit(10); // 触发事件

    return 0;
}

3. 观察者模式demo 

#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <algorithm>
#include <memory>
#include <ctime>

// ========== 天气站:观察者模式 (基于 std::function 回调) ==========

// ---- 事件类型 ----
enum class WeatherEvent {
    TEMPERATURE_CHANGE,
    HUMIDITY_CHANGE,
    STORM_WARNING
};

// ---- 主题 (Subject) ----
class WeatherStation {
    using Callback = std::function<void(WeatherEvent, double)>;

    struct Listener {
        int id;
        std::string name;
        Callback cb;
    };

    std::vector<Listener> listeners_;
    int next_id_ = 0;

    double temperature_ = 25.0;
    double humidity_    = 60.0;

public:
    int subscribe(const std::string& name, Callback cb) {
        int id = next_id_++;
        listeners_.push_back({id, name, std::move(cb)});
        std::cout << "  [订阅] " << name << " (id=" << id << ")\n";
        return id;
    }

    void unsubscribe(int id) {
        auto it = std::remove_if(listeners_.begin(), listeners_.end(),
            [id](const Listener& l) { return l.id == id; });
        if (it != listeners_.end()) {
            std::cout << "  [退订] id=" << id << "\n";
            listeners_.erase(it, listeners_.end());
        }
    }

    void notify(WeatherEvent event, double val) {
        for (auto& l : listeners_)
            l.cb(event, val);
    }

    void set_temperature(double t) {
        temperature_ = t;
        std::cout << "\n>>> 温度更新: " << t << "°C\n";
        notify(WeatherEvent::TEMPERATURE_CHANGE, t);

        if (t > 38.0) {
            std::cout << "!!! 触发高温风暴警告 !!!\n";
            notify(WeatherEvent::STORM_WARNING, t);
        }
    }

    void set_humidity(double h) {
        humidity_ = h;
        std::cout << "\n>>> 湿度更新: " << h << "%\n";
        notify(WeatherEvent::HUMIDITY_CHANGE, h);
    }
};

// ========== 具体观察者 (封装为类) ==========

class PhoneApp {
    int listener_id_;
public:
    explicit PhoneApp(WeatherStation& ws)
        : listener_id_(ws.subscribe("手机天气App",
            [](WeatherEvent e, double v) {
                switch (e) {
                    case WeatherEvent::TEMPERATURE_CHANGE:
                        std::cout << "  [手机App] 当前气温 " << v << "°C\n";
                        break;
                    case WeatherEvent::HUMIDITY_CHANGE:
                        std::cout << "  [手机App] 当前湿度 " << v << "%\n";
                        break;
                    case WeatherEvent::STORM_WARNING:
                        std::cout << "  [手机App] ⚠ 风暴警报!气温 " << v << "°C\n";
                        break;
                }
            })) {}
};

class SmartSpeaker {
    int listener_id_;
public:
    explicit SmartSpeaker(WeatherStation& ws)
        : listener_id_(ws.subscribe("智能音箱",
            [](WeatherEvent e, double v) {
                if (e == WeatherEvent::TEMPERATURE_CHANGE)
                    std::cout << "  [智能音箱] 语音播报:现在温度 " << v << " 度\n";
                else if (e == WeatherEvent::STORM_WARNING)
                    std::cout << "  [智能音箱] 🔊 警告:即将迎来恶劣天气!\n";
            })) {}
};

class ACController {
    int listener_id_;
public:
    explicit ACController(WeatherStation& ws)
        : listener_id_(ws.subscribe("空调控制器",
            [](WeatherEvent e, double v) {
                if (e != WeatherEvent::TEMPERATURE_CHANGE) return;
                if (v > 35.0)
                    std::cout << "  [空调] 开启制冷,目标 26°C (当前 " << v << "°C)\n";
                else if (v < 10.0)
                    std::cout << "  [空调] 开启制热,目标 22°C (当前 " << v << "°C)\n";
                else
                    std::cout << "  [空调] 关闭空调 (当前 " << v << "°C 舒适)\n";
            })) {}
};

class DataLogger {
    std::time_t start_time_;
    int listener_id_;
public:
    explicit DataLogger(WeatherStation& ws)
        : start_time_(std::time(nullptr))
        , listener_id_(ws.subscribe("数据记录器",
            [this](WeatherEvent e, double v) {
                if (e == WeatherEvent::TEMPERATURE_CHANGE)
                    std::cout << "  [数据记录] " << std::time(nullptr) << " 温度=" << v << " (启动后 " << (std::time(nullptr) - start_time_) << "s)\n";
            })) {}
};

class RangeObserver {
    double low_, high_;
    int listener_id_ = -1;
    WeatherStation* ws_;
public:
    RangeObserver(WeatherStation& ws, const std::string& name, double lo, double hi)
        : low_(lo), high_(hi), ws_(&ws) {
        listener_id_ = ws.subscribe(name + "(区间" + std::to_string(lo) + "~" + std::to_string(hi) + ")",
            [this](WeatherEvent e, double v) {
                if (e == WeatherEvent::TEMPERATURE_CHANGE) {
                    if (v >= low_ && v <= high_)
                        std::cout << "  [区间观察者] 温度 " << v << " 在 [" << low_ << "," << high_ << "] 范围内\n";
                    else
                        unsubscribe();
                }
            });
    }

    void unsubscribe() {
        if (ws_ && listener_id_ >= 0) {
            ws_->unsubscribe(listener_id_);
            listener_id_ = -1;
        }
    }

    ~RangeObserver() { unsubscribe(); }
};

int main() {
    std::cout << "=== 观察者模式 (Observer) - 天气站演示 ===\n\n";

    WeatherStation station;

    // 所有观察者都实例化为类对象
    PhoneApp      phone_app(station);
    SmartSpeaker  speaker(station);
    ACController  ac(station);
    DataLogger    logger(station);
    RangeObserver range_obs(station, "舒适温度监控", 20.0, 30.0);

    std::cout << "\n---------------- 模拟天气变化 ----------------\n";

    station.set_temperature(28.0);
    station.set_humidity(65.0);
    station.set_temperature(36.0);
    station.set_temperature(40.0);
    station.set_temperature(22.0);
    station.set_humidity(80.0);

    std::cout << "\n=== 演示结束 ===\n";
    return 0;
}

更多推荐