boost--function

本文详细介绍了C++标准库中的function模板类,包括其基本概念、如何使用function替代函数指针,以及如何在多种场景下利用function进行回调操作。此外还展示了如何结合bind和function实现给线程函数传递多个参数。

1、简介

  function是一个模板类,它就像一个包装了函数指针或函数对象的容器(只有一个元素)。可以把它想象成一个泛化的函数指针,而且他非常适合代替函数指针,存储用于回调的函数。如下定义了一个能够容纳void(int)类型的function对象:

function<void(int)> funo;

  使用function需要包含头文件"boost/function.hpp",C++11已经支持function。

  一些成员函数:

  target():返回对象内部的可调用物Functor的指针,对象为空则返回NULL
  contains():检测是否持有一个Functor。
  clear():将对象清空,与"= 0"效果相同。
  empty():测试对象是否为空,也可以在一个bool上下文中直接测试它是否为空。
  operator==、operator!=:与一个函数或函数对象进行比较。
  operator():调用内部的可调用物,它也会将参数传给可调用物。

2、简单使用

int FuncName(int a, int b)
{
    return a + b;
}

int main()
{
    function<int(int, int)> funo;
    funo = FuncName;
    if (funo)
    {
        cout << funo(3, 4) << endl;
    }

    return 0;
}
View Code

  除了普通函数,function对象中也可以存储Lambda表达式、函数对象(包括bind表达式的结果)、类的成员函数。我们完全可以使用function其来代替函数指针。

3、用于回调

  ①、存储普通函数

  以下为在CTestClass类中使用function对象m_fFun来保存回调函数和调用回调函数的示例,CTestClass的成员函数SetCallBack()被定义成了模板函数,这样更方便:

void call_back_func(int i)
{
    cout << i << endl;
}

class CTestClass
{
public:
    CTestClass(int i) :m_iNum(i) {}
public:
    template<typename CallBack>
    void SetCallBack(CallBack f)
    {
        m_fFun = f;
    }
    void run()
    {
        if(m_fFun)
            m_fFun(m_iNum);
    }
private:
    function<void(int)> m_fFun;
    int m_iNum;
};

int main()
{
    CTestClass dc(10);
    dc.SetCallBack(call_back_func);
    dc.run();

    return 0;
}
View Code

  ②、存储Lambda表达式

class Bar
{
public:
    std::function<void()> onClick;
};

class Foo
{
public:
    Foo()
    {
        b = new Bar;
        //存储Lambda,捕获this指针,使lambda内可调用本类的成员
        b->onClick = [this] {
            func();
        };
    }
    void func()
    {
        cout << "func" << endl;
    }
private:
    Bar* b;
};

int main()
{
    //存储Lambda,捕获变量num
    int num = 100;
    std::function<void()> f = [num] {
        cout << "num:" << num << endl;
    };
    f();

    getchar();
    return 0;
}
View Code

   ③、存储函数对象

  使用function来存储函数对象是function的重要功能之一,因为相比于使用普通函数回调,使用函数对象回调可以保存数据和实现复杂的操作。以下为在CTestClass类中使用function对象m_fFun来保存回调函数对象和调用回调函数对象的示例

#include "boost/bind.hpp"
class CFunObj
{
public:
    CFunObj(int i) :x(i) {}
public:
    void operator()(int i)
    {
        cout << i * x++ << endl;
    }
private:
    int x;
};

class CTestClass
{
public:
    CTestClass(int i) :m_iNum(i) {}
public:
    template<typename T>
    void SetCallBack(T f)
    {
        m_fFun = f;
    }
    void run()
    {
        if (m_fFun)
            m_fFun(m_iNum);
    }
private:
    function<void(int)> m_fFun;
    int m_iNum;
};

int main()
{
    CTestClass dc(10);
    CFunObj cfo(2);
    dc.SetCallBack(ref(cfo));
    dc.run();
    dc.run();

    return 0;
}
View Code

  function使用拷贝语义来保存函数或函数对象,当函数或函数对象很复杂或者禁止拷贝的时候可以使用ref()以解决拷贝的问题。从以上示例代码可以看到,在使用SetCallBack设置回调的时候就是使用ref()来传递的引用包装器,SetCallBack是模板函数,所以T类型在函数调用的时候就是ref()引用包装类型。

  ④、存储类的成员函数

  以下我们定义了一个函数工厂类,回调函数都在这个工厂类中定义,我们可以配合bind来保存类中的回调函数,然后通过fiunction对象再调用类中的回调函数:

#include "boost/bind.hpp"
class CCall_back_factory
{
public:
    void call_back_fun_1(int i)
    {
        cout << i * 2 << endl;
    }
    void call_bcak_fun_2(int i, int j)
    {
        cout << i * j * 2 << endl;
    }
};

class CTestClass
{
public:
    CTestClass(int i) :m_iNum(i) {}
public:
    template<typename CallBack>
    void SetCallBack(CallBack f)
    {
        m_fFun = f;
    }
    void run()
    {
        if(m_fFun)
            m_fFun(m_iNum);
    }
private:
    function<void(int)> m_fFun;
    int m_iNum;
};

int main()
{
    CTestClass dc(10);
    CCall_back_factory cbf;
    
    dc.SetCallBack(bind(&CCall_back_factory::call_back_fun_1, cbf, _1));
    dc.run();

    int j = 5;
    dc.SetCallBack(bind(&CCall_back_factory::call_bcak_fun_2, cbf, _1, j));
    dc.run();

    return 0;
}
View Code

 通过以上示例代码可以看到,function用于回调再配合bind解决了类的成员函数不能作为回调函数的问题,而且使用更加灵活。 C++中A类对象里调用B类对象的成员函数一般使用以下三种方法:

  ①、使用虚函数:在A类中保存B类对象的基类指针m_ptr,在B类中重写基类的虚函数,通过B类的基类指针m_ptr来调用B类的虚函数。
  ②、使用function + bind:在A类中保存B类对象的成员函数的function(通过bind),通过function来调用B类的成员函数。
  ③、使用function + lambda:在A类中保存B类对象的成员函数的function(通过捕获this指针的lambda),通过function来调用B类的成员函数。

4、给线程函数传入多个参数

  我们知道,线程函数只有一个void*参数,利用bind和function可以间接实现给线程函数传入多个参数:

#include <Windows.h>
#include "boost/bind.hpp"

void RealFun(char* p, int& n)
{
    cout << p << n << endl;
    n = 0;
}

DWORD WINAPI ThreadFunc(void* param)
{
    function<void()> func = *((function<void()>*)param);
    func();

    return 0;
}

int main()
{    
    char* p = "value is :";
    int i = 10;

    function<void()> func = boost::bind(&RealFun, p, ref(i));
    HANDLE hThread = CreateThread(NULL, 0, ThreadFunc, &func, 0, 0);
    WaitForSingleObject(hThread, INFINITE);
    
    assert(i == 0);

    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/milanleon/p/7498849.html

### 关于Buck-Boost电路仿真的方法、软件和工具 #### MATLAB/Simulink作为主要仿真平台 MATLAB/Simulink 是一种广泛应用于电力电子领域仿真的强大工具。对于 Buck-Boost 变换器的仿真,可以通过 Simulink 提供的模块库快速构建电路模型。例如,在引用中提到的内容显示了一个基于 MATLAB 2017b 的 Buck-Boost 变换器仿真模型[^1],该模型不仅支持反相 Buck-Boost 结构,还涵盖了四管同相结构的设计。 #### 不同类型的 Buck-Boost 模型及其特点 在实际应用中,存在两种常见的 Buck-Boost 架构: 1. **反相 Buck-Boost**:这种架构的特点是输出电压极性与输入相反。其基本原理依赖单个电感以及开关器件完成能量转换过程。 2. **四管同相 Buck-Boost**:相比反相结构,此架构能够提供更高效率和更大输出电流能力。它通过四个开关管协同工作实现更稳定的能量传输,并允许负载端获得正向输出电压[^3]。 #### 参数设置与优化 为了验证 Buck-Boost 变换器的工作特性,通常需要调整多个关键参数,比如开关频率、占空比范围、滤波电容值等。以某具体实例为例,当系统处于稳态运行状态时,可观察到 A 通道代表电感电流纹波约为 \(175.79 \, \text{mA}\),而 B 通道则对应输出直流电压大约为\(-6.006 \, \text{V}\)[^4]。这些数据有助于评估设计是否满足预期目标。 #### 故障诊断策略 除了正常工况下的行为研究外,还需要考虑异常条件对整个系统的干扰作用。为此引入了一套完整的故障诊断流程,主要包括以下几个方面: - 创建各种典型失效场景(如短路、开路或者元器件规格偏差),以便全面了解可能出现的问题; - 利用上述建立起来的测试环境开展实验活动,记录下因错误引发的变化趋势; - 针对所得结论制定相应的防护方案,从而增强最终产品的鲁棒性和安全性水平[^2]。 ```matlab % 下面是一个简单的Matlab脚本用于初始化Simulink中的Buck-Boost模型参数 function setup_buck_boost_model() % 设置默认参数 sim('myBuckBoostModel'); set_param('myBuckBoostModel/Constant','Value','12'); % 输入电压设为12伏特 set_param('myBuckBoostModel/PWM Generator','Frequency','10e3'); % PWM信号频率定为10kHz end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值