1

C++ に変換している Java メッセージング API があります。メッセージは通常、string、int、double などの単純なデータ型を持ちます。メッセージが作成されると、すべてのメンバー変数がデフォルト値に初期化されます。このデフォルト値は、API が「null」値として認識します (つまり、どの値にも設定されません)。 )、たとえばInteger.MAX_VALUEint 型の場合。null と見なされるフィールドはシリアル化されず、送信されません。

Java では、文字列は自動的に に初期化されるnullため、null の文字列フィールドと空の文字列 (メッセージで送信する正当な値) の文字列を簡単に区別できます。

文字列は自動的に空の文字列に初期化され、空の文字列は API 経由で送信する正当な値であるため、C++ でこれを処理する最善の方法はわかりません。文字列を何らかの制御文字にデフォルト設定することもできます (これは API では正当な値ではありません) が、これを行うためのより従来の方法またはより良い方法があるかどうか疑問に思っています。

私たちは皆 C++ に慣れていないので、明らかなアプローチを見落としている可能性があります。

4

2 に答える 2

5

推奨される方法は、有効な値を持つまでオブジェクトが存在しないようにすることです。null 文字列を含むメッセージが有効でない場合、なぜそれを許可するのでしょうか?

文字列は常に null になる可能性があるため、Java ではこれを避けることはできません。しかし、C++ は、常に文字列を保持することが保証されているクラスを作成するためのツールを提供します。

そして、それがあなたが望んでいるように聞こえます。

あなたが求めているものについて、最善のアプローチは、このクラスのオブジェクトが常に文字列 set を持っているという不変条件をクラスに組み込むことです。コンストラクターですべてのオブジェクトを既定値に設定する代わりに、コンストラクターを定義して実際のパラメーターを受け取り、メンバーを有効な値に設定します。

ただし、「オプション」の値を指定する場合は、いくつかの広範なアプローチがあります。

  • ポインター (できればスマート ポインター) を使用します。文字列へのポインターは、null にすることも、有効な文字列を指すこともできます (これも、空である場合と空ではない場合があります)。
  • boost::optionalまたは、 Boost ライブラリのようなものを使用します。これは、オプションの値を定義できる賢い小さなユーティリティ テンプレートです (オブジェクトには文字列が含まれる場合もあれば、null の場合もあります)。
  • boolまたは、単にフラグを追加することもできます(has_string設定されていない場合は、文字列が設定されておらず、文字列値を無視する必要があることを示す のようなもの)。

個人的には、最後の 2 つのアプローチを好みますが、3 つすべてがかなり一般的に使用されており、問題なく動作します。しかし、最良のアプローチは、クラスが常に有効であることをコンパイラーが保証できるようにクラスを設計することです。ヌル文字列を含むメッセージが必要ない場合は、メッセージにヌル文字列が含まれないようコンパイラーに保証させます。

于 2013-06-18T18:54:30.797 に答える
2

Java の「値を持っていても、値を欠いていてもよい」Java を複製するには、おそらく最も一般的な方法は、 を保存boost::optional<T>するか、標準の次のバージョンにstd::optional<T>.

それらの値を読み取りたい場合は、いくつか*を投入する必要があります。デフォルトの変換は「初期化されているかどうか」であり、保存されている ではありません。しかし、それに書き込むときは、たいていのことを行います。コンテキストで予期しないことを行うことができるのは、それから読み取るだけです。->optional<bool>boolbooloperator=bool

が初期化されているかどうかを確認するには、ポインターのようにコンテキストoptional<T>で評価します。bool初期化されたことを確認した後でその値を抽出するには、単項演算子を使用します*

boostは比較的高品質のライブラリであり、5 年から 10 年でそこから C++ 標準に移行するコードの割合が高いです。これにはいくつかの恐ろしい部分 (フェニックスなど) が含まれており、一般に、使用しているコンポーネントが C++ 標準ライブラリにまだ含まれていない (そこに移行されている) ことを確認する必要があります。 boost::optional特に、使いやすいヘッダーのみのライブラリの一部です (boost使用するためにビルドする必要がないため)。

于 2013-06-18T19:13:21.660 に答える