从 C++ 中的另一个对象执行方法

Method execution from another object in C++

首先请允许我介绍一下我的 class 结构。我正在为 ARM 设备 (STM32) 设计一个小库,我想实现几个定义系统上可用的不同外设的对象。

class xGPIO : public Peripheral 
{
public:
    xGPIO();
    xGPIO(GPIO_TypeDef * GPIOx1, uint16_t Pinx1);
    virtual ~xGPIO();

    void on(void);
    void off(void);
private:
    void xInitGPIO(void);

};

我的想法是实现一个名为 callback 的内部 public 函数,它设置下一个要在我的计时器对象上调用的函数。但是这个函数肯定是另一个 class 中定义的方法,我希望它从 xTimer 中执行。这里的行为,应该是每当 Timer 结束倒计时时,它应该调用程序员存储在 callBack 方法中的函数。

class xTimer : public Peripheral 
{
public:
    xTimer(TIM_TypeDef * tim);
    virtual ~xTimer();
    /* void callBack(void (*f)()); */

private:
    void xInitTimer(void);
    TIM_HandleTypeDef htim;
};

void xTimer::callBack(void (*f)())
{
   f();
}

main.cpp下的代码如下:

int main(void)
{
    mySYS->initialize(false);

    xGPIO myGreenLed (GPIOB, GPIO_PIN_0);

    /* Declare Timers.  */
    xTimer myTimer(TIM2);    
    // myTimer.callBack(myGreenLed.on);
}

关于如何解决这个问题的任何线索?有没有一种简单的方法可以在 C++ 程序上遵守该设计?

您正在使用 C 模式。 C++ 具有更强大的 std::function。您的 xTimer::callBack 应定义为

void xTimer::callBack(std::function<void(void)> f) { f(); }

所以它可以被称为

myTimer.callBack([&](){myGreenLed.on()}); //using lambda

myTimer.callBack(std::bind(&xGPIO::on, &myGreenLed));

直接使用模板也可以不用std::function:

template<class T>
class xTimer : public Peripheral 
{
public:
    xTimer(TIM_TypeDef * tim);
    virtual ~xTimer();
    void callBack(T &obj, void (*T::f)())
    {
        (obj.*f)();
    }

private:
    void xInitTimer(void);
    TIM_HandleTypeDef htim;
};

并且可以像这样使用:

xTimer<xGPIO> myTimer(TIM2);    
myTimer.callBack(myGreenLed, &xGPIO::on);

然后您将失去 std::function 的灵​​活性,并且它不适用于 std::bind 和 lambda,但获得了没有 allocation/deallocation 的优势。

模板也可以只在 callback 级别,但我想您实际上想要存储值并稍后调用它,那么您需要对存储进行模板化。

如果您调用的方法只是特定单一类型的成员(即总是 xGPIO),那么您甚至不需要模板。

另请注意,如果您存储要稍后调用的对象实例,则必须确保该对象的生命周期保持不变,直到您需要调用它(或者您需要制作一个副本,使用 std::shared_ptr ETC。)。这也适用于使用 std::function 和对象指针或 std::ref.