2017-09-27 21 views
0

私の要件は、XMLを解析してオブジェクトを生成することです。オブジェクトがXmlから取り込まれると、属性xyzが存在するかどうかを自動的にトラッキングする方法を教えてください。オブジェクトが移入された後は、解析されたバッファにアクセスできなくなることに注意してください。したがって、属性がXMLに存在するかどうかを知るためのメカニズムが必要で、オブジェクトにその属性が設定されています。属性の有無のチェック

私には以下の解決策がありますが、もっと効率的なものがあるかどうかはわかりません。また、私はこの問題の一般的な解決策を探しています。

  • クラス内の各属性のビットを定義します。属性が存在する場合、XMLの解析中

  • セッター関数はそのビットを設定する必要

  • ゲッター関数は、参照引数で属性値を返す前にビットをチェックすべきです。ビットが設定されていない場合は、falseを返す必要があります。 (getter関数の戻り値の型はboolean型である必要があり、それは、type属性の1つの引数を受け入れ、存在する場合、それを移入)私はあなたがデザインを変更することができることを集めるあなたのコメントから

+0

最後の箇条書きは、偽を返すことができ、または参照によって属性を返すことを意味します。もう少し具体的にして、「オプション」を返さなければならないと言うでしょう。 – AndyG

+0

あなたは属性の存在を追跡する必要があると言いますが、存在する場合は参照を返したいとします。したがって、属性の存在のみを保持するデータ構造は不十分である。その情報のオブジェクトをクエリにすることができるときに、属性がXMLに含まれているかどうかを追跡する必要があるのはなぜですか? – patatahooligan

+0

@andygはそれに応じてステートメントを更新しました。 – Sitesh

答えて

1

、これは何です私はやります:

前者が利用できない場合は、すべてのオプションメンバーを適切な名前のstd::optionalまたはそれと同等のものに置き換えてください。

using std::optional; // facilitates easy switching between std and boost if needed 

class MyClass { 
    optional<int> some_value; 
    // Similarly for rest of attributes 

    void set_some_value(int value_to_store) { some_value = value_to_store; } 

    optional<int> get_some_value() { return some_value; } 
} 

MyClass instance; 
// ... parse XML and set attributes 
auto some_value = instance.get_some_value; 
if (some_value) { 
    do_something_with_int(*some_value); 
} 

optionalに関する注意次のようにそれを行うからの読み取りに:

  • デフォルト・構築optional sが空であるが。つまり、明示的に設定しない属性はすべてデフォルトでは空です。

  • 空のオプションの参照解除は、未定義の動作です。それにアクセスするより安全な方法があります。この例では、とにかく属性の存在を分岐させたいと思っているので、手動でチェックしたので安全です。

  • 管理オブジェクトは、割り当てられたoptionalオブジェクトの内部にあることが保証されています。これは、スピードに優れた動的割り当てを意味しません。ただし、大きなオブジェクトがある場合、スタックオーバーフローの問題が発生する可能性があります。しかし、大規模オブジェクトのほとんどの実際のシナリオでは、stringや、とにかくヒープ上にデータを保持するSTLコンテナ/ラッパーを使用しているため、そうは思わしくありません。

  • 標準でスペースコストの記載が見つかりませんでした。私はそれが典型的にすべてのオプションのオブジェクト内に単一のboolで実装されていると信じています。 sizeof(bool)は、多くの場合、sizeof(int)です。これにより、必要以上に多くのスペースが必要になりますが、可能な限り高速です。これは一般的には良いトレードオフですが、メモリ使用の問題が発生し、多くのオブジェクトがoptionalを保持している場合は、よりスペース最適なソリューションを見つける必要があります。センチネル値を使用して存在しないことを知らせることができる場合は、コンパクトなオプションのオブジェクトの実装を参照してください。

+0

解決方法は涼しいですが、残念ながらstd :: optionalはC++ 17のユーティリティです。私たちは現時点ではC++ 11を使用していますが、C++ 17へのアップグレードはまもなく表示されません。 – Sitesh

+0

最初の行を ' boost :: optional'を使用します。それもオプションでない場合は、同じインタフェースを実装する独自のオプションクラスを作成してください。 – patatahooligan

+0

最初の行を変更するとどうなりますか?説明していただけますか? stdオプションはC++ 11でも利用できますか? – Sitesh

関連する問題