2017-02-03 13 views
2

私はいくつかのクラス(プッシュボタン用、ポテンショメータ用、ロータリーエンコーダ用など)を持つMIDIコントローラライブラリで作業しています。これらすべてのクラスには、sendMIDI関数を使用するメソッドがあります。また、プログラムの最初に一度呼び出されるsetupMIDI関数もあります。 setupMIDIには、sendMIDI関数でアクセスする必要がある3つのパラメータがあります。クラスのライブラリ内のグローバル変数を取り除く

定義

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(); 
} 

、アナログおよびデジタルのクラスのすべてのインスタンスを使用します同じsendMIDI関数であり、これはsetupMIDI関数に入力された値に依存します。問題は、これらの値がグローバル変数に格納されていることです。これは理想的ではありません。

私はMidiSenderクラスの使用について考えましたが、そのインスタンスをすべてのアナログまたはデジタルコンストラクタに渡す必要があります。

これを回避するより良い方法はありますか?

ありがとうございます!代わりに、いくつかのグローバル変数を設定setupMIDI機能を有するの
ピーター

+0

あなたはこの文を明確でした:* "[...]理想的ではないグローバル変数、で" *?私は以下の答えに同意します*すべての変数をまとめた文脈は確かに優れていますが、なぜグローバルに宣言し、参照渡しがグローバルにアクセス可能な静的**少なくともシングルトン**であることが意図されている場合には、例えば、同じ解決策が 'Serial.begin(...)'に適用されます。 –

+0

問題は、例えば、ユーザーが 'pin'変数を作成しようとするとライブラリが動作しないことです。 Serialのような実装方法に関するリンクを教えてください。または、いくつかの検索条件ですか? ありがとう! – tttapa

+0

まあ、名前空間の競合を解決するには**名前空間**を使うことができます。* imho *同じ*コンテキスト*または*インスタンス*内の関連する変数を適切に囲むには、**良い設計**の練習が必要です。しかし、**あなたのmidiが**シングルトン**であることを意図している場合、私はそれがグローバル*および*ユニーク*インスタンスであると悪いことは何も見ません。 ** Serial **の例は、「HardwareSerial0.cpp」の宣言(67行目〜71行目)とクラスの実装のための「HardwareSerial.h/.cpp」を調べるのはかなり簡単です。ソースコードは** github **:https:// githubにあります。com/arduino/Arduino –

答えて

4

は、それらの値を格納し、そのコンストラクタを介してそれらを初期化しMIDIContextクラスを持っています。

pin

のユーザ、delayTime、及びdebugいずれか方法MIDIContextであるか、または値にアクセスするMIDIContext&const&適切な)を取ります。

例:

class MIDIContext 
{ 
private: 
    byte pin; 
    int delayTime; 
    bool debug; 

public: 
    MIDIContext(byte x_pin, int x_delayTime, bool x_debug) 
     : pin{x_pin}, delayTime{x_delayTime}, debug{x_debug} 
    { 
    } 

    void sendMIDI(); 
}; 

class Analog 
{ 
    void refresh (MIDIContext& ctx); 
}; 

可能な用法:

Analog a1(...); 
Analog a2(...); 
Digital d1(...); 

MIDIContext context(13, 10, true); 

while(true) { 
    a1.refresh(context); 
    a2.refresh(context); 
    d1.refresh(context); 
} 
+0

ありがとう!コンテキストをパラメータとして渡すことなく、簡単な方法があるのか​​どうか疑問に思っていましたが、これは実際には最も簡単な方法です。 – tttapa

+0

このテクニックは、コードスレッドを安全にするための長い道のりです。 –

+1

@brianbeuning:どのようなardunioスレッドがありますか? – dandavis

関連する問題