c++ - 类模板实例化 : any way round this circular reference?

标签 c++ templates embedded

我有两个类用来表示一些硬件:一个 Button 类和一个 InputPin 类,它们表示一个按钮,当它被按下时会改变 IC 输入引脚的值。它们的一个简单示例是:

template <int pinNumber> class InputPin 
{
  static bool IsHigh()
  {
     return ( (*portAddress) & (1<<pinNumber) );
  }
};

template <typename InputPin> class Button 
{
  static bool IsPressed()
  {
    return !InputPin::IsHigh();
  }
};

通过使用类模板,这工作得很好,下面的条件将像我在汇编中手写它一样紧密地编译(一条指令)。

Button < InputPin<1> > powerButton;

if (powerButton.IsPressed())
   ........;

但是,我正在扩展它以处理中断并且遇到循环引用问题。

与原来的InputPin相比,新的InputPinIRQ类多了一个静态成员函数,当引脚值改变时,硬件会自动调用该成员函数。我希望它能够通知 Button 类,以便 Button 类可以通知主应用程序它已被按下/释放。我目前通过将指针传递给回调函数来做到这一点。为了让编译器内联回调代码,我认为需要将这些函数指针作为模板参数传递。所以现在,这两个新类都有一个额外的模板参数,它是一个指向回调函数的指针。不幸的是,这给了我一个循环引用,因为要实例化一个 ButtonIRQ 类,我现在必须做这样的事情:

ButtonIRQ<InputPinIRQ<1, ButtonIRQ< Inp.... >::OnPinChange>, OnButtonChange> pB;

其中......代表循环引用。

有谁知道如何避免这种循环引用?我是模板的新手,所以可能遗漏了一些非常简单的东西。

附言。重要的是,编译器确切地知道中断发生时将运行什么代码,因为它随后会进行一些非常有用的优化——它能够内联回调函数,并将回调函数的代码直接插入到 h/上调用的确切地址w 中断。

最佳答案

我会更改设计,使按钮与输入引脚相关联:

class Button
{
  boost::smart_ptr<InputPin> p_input_pin;
}

或者更改 pin 类,使其具有订阅者列表。这可能是更好的设计,因为它允许在 pin 更改其值时通知许多订阅者。您还可以添加一个方法 (setter) 来设置引脚的值。

用例 1:按下按钮。
按下按钮更改输入引脚的状态。
输入 pin 通知订阅者事件。

用例 2:中断。
中断 {object} 改变输入引脚的状态。
输入 pin 通知订阅者事件。

订阅者/发布者设计模式非常适合这些用例。

关于c++ - 类模板实例化 : any way round this circular reference?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3048107/

相关文章:

templates - thymeleaf :text - Put a text without removing HTML structures

c - 在嵌入式 c 中使用 printf

c++ - 如何将值写入 DIO 模块 AUTOSAR 中的端口?

c++ - 如何让 Windows Mobile 模拟器上的文件夹共享工作

C++ 错误 : identifier "barCode" is undefined

c++ - 是否可以将带逗号的语句传递到 boost 测试宏中?

c++ - 在目标函数中使用迭代器的 STL 算法

linux - snmpv3 通知/陷阱 c 代码

c++ - CMake:如何设置 VTK_DIR?

c++ - 将 VirtualProtect EAT Hook 例程从 C 转换为 Delphi 的 Delphi 问题