【发布时间】:2017-02-03 12:20:02
【问题描述】:
我正在开发一个 MIDI 控制器库,它有几个类(例如,一类用于按钮,一类用于电位计,一类用于旋转编码器等)。所有这些类都有使用 sendMIDI 函数的方法。还有一个 setupMIDI 函数,在程序开始时调用一次。 setupMIDI 接受三个参数,需要通过 sendMIDI 函数访问。
类的定义
class Analog {
public:
Analog (...) { ... }
void refresh () {
...
sendMIDI(x, y, z, ...);
...
}
}
class Digital { ... (also uses sendMIDI) ... }
etc.
setupMIDI 和 sendMIDI 函数
byte pin;
int delayTime;
bool debug;
void setupMIDI (byte p, int d, bool db = false) {
...
pin = p; delayTime = d; debug = db;
...
}
void sendMIDI ( ... ) {
...
if(debug) ...
digitalWrite(pin, 1);
delay(delayTime);
...
}
实际程序:
Analog a1( ... );
Analog a2( ... );
Digital d1( ... );
setupMIDI(13, 10, true);
while(true) {
a1.refresh(); // calls sendMIDI
a2.refresh();
d1.refresh();
}
如您所见,Analog 和 Digital 类的所有实例都使用相同的 sendMIDI 函数,这取决于在 setupMIDI 函数中输入的值。问题是这些值存储在全局变量中,并不理想。
我曾考虑过使用 MidiSender 类,但这需要将它的一个实例传递给每个 Analog 或 Digital 构造函数。
有没有更好的方法来解决这个问题?
非常感谢!
彼得
【问题讨论】:
-
您能否澄清一下这种说法:“[...] in global variables, which is not Ideal”?我同意下面的答案,将所有变量包装在一起的 context 肯定更好,但我不明白为什么全局声明它并通过引用传递它比简单地将它作为全局可访问更好静态资源,至少在它应该是一个单例的情况下。例如,同样的解决方案适用于
Serial.begin(...)。 -
问题是如果用户尝试创建一个
pin变量,库将无法工作。你能指出一个关于如何实现像串行这样的东西的链接吗?或者也许是一些搜索词?谢谢! -
好吧,您可以使用 namespaces 来解决名称冲突,imho 这更多的是 good design 实践在同一 context 或 instance 中正确封装相关变量。但是,如果你的 midi 是一个 singleton,那么我看不出它是一个 global 和 有什么不好唯一的 实例。 Serial 的示例很容易理解,请查看“HardwareSerial0.cpp”中的声明(第 67-71 行)和“HardwareSerial.h/.cpp”中的类实现。 github上提供源代码:github.com/arduino/Arduino
标签: c++ class arduino global-variables