1

私は、いくつかのプロジェクトで使用する C++ の小さなフレームワークに取り組んでおり、一種のユーティリティ ライブラリとして静的にリンクしています。私の個人的なニーズに合わせてドメイン固有のものや、ジュースのような単純なライブラリと比較できると思いますこれは何よりも学習と経験の練習なので、時間をかけて適切に行い、適用する技術を理解したいと思います. 私は現在 Linux で作業していますが、コードを移植可能にすることを目指しているため、プラットフォーム固有のコードをインターフェイスに書き込むことができます。

現時点では、さまざまなタイプのオブジェクトを含むメッセージを許可したい基本的なメッセージング システムに取り組んでいます。私の最初の考えは次のようなものでした:

class Message {
  virtual std::string type;
};
class DataMessage : Message {
  std::vector<std::string> *data;
};

私の質問は、 Message が DataMessage であることを識別し、それを実際の型にキャストするか、含まれているデータにアクセスする最良の方法は何ですか?

上記のように型に文字列を使用できますが、各サブクラスが実際に一意の型 ID を持つことは保証されません。また、文字列処理のオーバーヘッドが代替手段よりも遅くなるかどうか疑問に思います (たとえば、列挙型を拡張できますか?)。

データへのアクセスに関しては、メッセージを適切な型にキャストできれば問題ありません。それ以外の場合は、仮想関数をアクセサーとして基本クラスに追加できます (しかし、基本クラスで指定されたものとは異なる戻り値の型を使用するにはどうすればよいでしょうか? クラスが追加のデータを必要としない場合はどうなるでしょうか? )、またはデータに作用するワーカー関数として(しかし、コールバックスタイルのフレームワークではなく、クラス間のデータ受け渡しメカニズムとして使用したいのですが)。

提案、代替案、またはリンクは大歓迎です。さまざまなアプローチについて議論するのは素晴らしいことです。

よろしくお願いします。

4

3 に答える 3

3

私の質問は、 Message が DataMessage であることを識別し、それを実際の型にキャストするか、含まれているデータにアクセスする最良の方法は何ですか?

あなたはそれをすべきではありません!
そうすると、デザインが弱くなります。基本的に、 SOLID パラダイムの基本原則の 1 つである「Liskov Substitution Principle」を破ることになります。
オブジェクトの具象型に応じてアクションを実行する場合、コード内のどこにいても、インターフェースではなく実装に対してコーディングしていることに注意してください。基本的な設計ガイドラインは
、「実装ではなくインターフェイスへのコード」です。
具象型へのコーディングを開始すると、コードの保守が難しくなり、密結合になります。新しい派生クラスを追加するたびに、コードはさらに分解され、寛大さが失われます。

代わりに、ポリモーフィズムに頼ってタスクを実行する必要があります。基本クラスに仮想メソッドを実装し、派生クラスで適切にオーバーライドする必要があります。このようなメソッドを呼び出すだけで、ランタイムは各クラスで適切なメソッドを呼び出すことができます。これは、ランタイムが具象型が何であるかを 知っているためです。重要なのは、作成するコードが型を知る必要がないことです。

テンプレートメソッドパターンのような良いパターンをチェックしてみてください。

于 2012-06-25T04:44:27.603 に答える
2

を使用できますDataMessage* pDataMessage = dynamic_cast<DataMessage*>(pMessage)。はオブジェクトのpDataMessage場合にのみ有効です。それ以外の場合はになります。pMessageDataMessageNULL

于 2012-06-25T04:29:42.033 に答える
2

typeid 演算子を使用します。これは C++ RTTI の一部です。ほとんどすべてのコンパイラがサポートしています。これが独自のフレームワークである場合は、データ フィールド (enum 型の方が優れている) を使用するアプローチもそれほど悪くはありません。

于 2012-06-25T04:21:50.050 に答える