2009-08-11 13 views
1

可変数の引数を持つSetParams(...)というC関数があります。この関数は、静的なデータ構造を設定します(Dataと名付けましょう)。 SetParamsは引数のペアとともに使用されます。Cで可変数のargsを持つ関数と設計指向の質問

Execute(); 
// uses data from static 'Data' and performs error_handling and execution 
:すべての「パラメータ」が設定されている場合は、別の関数が呼び出された e.g.

SetParams("paramA", paramA_value); 
SetParams("paramB", paramB_value); 
... 

また、何度も呼び出すことができるなどSetParams("paramA", paramA_value, "paramB", paramB_value)、それは何の引数を取りません(私たちはそれExecuteに名前を付けましょう)

私はこの種のコードをよりオブジェクト指向の方法で構造化できるかどうか疑問に思っていました。ですから、いくつかの組のargsが他のものと矛盾するかもしれないので、特にエラー処理のためのアドバイスをお願いしたいと思います。

+0

あなたは正確に何をしようとしていますか?"SetParams"を何度も呼び出すだけでなく、結果をスタックにプッシュしてexecuteを呼び出す前に、スタックからすべてを取り出して使用する理由はありますか? – Goz

+0

SetParamsは、シミュレーションの入力データを設定します。問題は、以前のものと矛盾するargペアがますます追加されることです。たとえば、誰かが次のことを行うことができます: SetParams( "Solve Method"、methodNameA、 "Param A"、10); ここで、 "Param A"はmethodNameAの変数で、次に: SetParams( "Solve Method"、methodNameB)です。ここで、methodNameBには "Param A"変数はありません。それは私がキャッチしたいエラーです。この関数は、スクリプトを使用してプログラマー以外から呼び出されます。私には何らかのスタック実装を使用することはできませんでした。私はそれを与えるだろう:)。ありがとうございました。 –

答えて

1

リンクリストを使用してパラメータを格納し、すべてのメソッドを構造体の関数ポインタとして配置することをお勧めします。

struct MyClass { 
    struct LinkedList* params; 
    void (*setParams)(...); 
    void (*execute)() 
} 

リンクリストは、私はあなたがあなたのSetParamsメソッドは、それはほんの少しの解析と保存のビットと転送エラー処理を行い、音から、実施しているか知らないキーと値のペア

struct LinkedList { 
    struct LinkedList *next; 
    char * key; 
    char * value; 
} 
0

だろうExecuteコールの下流。 可変長引数を使用しているので、va_ *マクロを使用していますか?書式文字列を使用すると、エラー処理をSetParams呼び出しに挿入し、Executeが値を反復処理してその処理を実行できるようになります。

一般に、パラメータの設定に関連するエラーを管理する必要がある設定パラメータを処理する関数があるとします。コマンドの実行中に発生したエラーは、実行機能で対処する必要があります。

+0

SetParamsで多くのエラーを検出する可能性があります。しかし、何かが多くの 'SetParams'呼び出しで定義される可能性があり、問題定義に追加するために他の 'SetParams'を呼び出すことができないことを知りませんので、エラーとしてマークします。 –

0

C可変長関数ではあなたが提供した引数の数を知らないので、何らかの方法でそれを知っておく必要があります。たとえば、最初のパラメータとしてパラメータ数を指定するか、printfの方法フォーマット文字列からパラメータの数を見つけることができます。

+0

実際には、SetParamsは引数として構造体を取ります。可能な引数をクエリします。例えば、 if(has_pair( "SomeName"、value of value、&value))... –

+1

@John次に、役職。 – qrdl

2

Cでオブジェクト指向設計を作成する一般的な方法は、すべてのクラスメンバー変数を格納するために使用される構造体への参照で渡すすべてのメソッド用です。あなたがlistObj.clear()を持っているC++の他の言葉では、C list_clear(&listObj)にあります。

これは醜いですが、静的メンバー変数を使用し、実装を1回だけ使用することを制限しない限り必要です。各方法において構造体ParamUtilObjへの参照が渡される方法を以下の例で

は、気付く。

// --- paramUtil.h 

// Stores all the objects member variables (public and private) 
struct ParamUtilObj { 
    int paramCnt; 
    char param1[25]; 
    char param2[25]; 
    ... 
}; 

bool paramUtil_initialize(struct* ParamUtilObj pData); 
bool paramUtil_addParam(struct* ParamUtilObj pData, const char* pKey, const char* pValue); 
bool paramUtil_execute(struct* ParamUtilObj pData); 

可変長方法に関して。私は可能な限り避け、一度に1つずつ追加するようにしています。 paramsを検証するビジネスロジックは、私の意見では全く別の話題です。私は最良のアプローチを推薦するためにもっと多くの情報が必要です。しかし、...(MethodA)が他の引数があるかどうかをチェックするなどの検証をしなければならないので、私のように思えます。ユーザがそれぞれのMethodTypeに対していくつかのSetParamメソッドを作成する方が簡単かもしれませんスクリプトで指定することができます。

関連する問題