6

stringhandler、SomeTypeHandler、AnotherTypeHandlerなどのサブクラスを持つクラスハンドラーがあるとします。クラスHandlerは、メソッド「handle」をすべてのサブクラスの共通インターフェースとして定義します。もちろん、「処理」するロジックは、ハンドラーごとに完全に異なります。

だから私がする必要があるのは、handleメソッドに何かの値を渡すことです。特定のクラスは、「何でも」を期待するタイプにキャストできます。

基本的に私が必要としているのは、JavaクラスObject:Dのようなものです。

私が最初に試したのはでしたvoid*が、どうやらあなたはできないのでB* someB = dynamic_cast<B*>(theVoidPointer)、そこには運がありません。

私の2番目のアイデアはを使用することでしたboost::any。ただし、boost :: anyを使用するための要件は、値がコピーで構造化可能でなければならないことです。これは、私のデータには当てはまりません。

これを機能させるためのアイデアはありますか?

ありがとう

編集:メンバーがまったくないSomeDataクラスを使用して、データをそのサブクラスにすることができることはわかっていますが、独自のラッパークラスを作成する必要のないより一般的なアプローチを探しています。

4

5 に答える 5

1

たとえば、基本クラスを定義できます。

class BaseHandlerData {
   ...
};

次に、ハンドラーによって期待される特定のデータクラスを導出します。

class StringData: public BaseHandlerData {
   ...
};

class SomeData: public BaseHandlerData {
   ...
};

次に、BaseHandlerData *引数をhandleメソッドに渡して、次のようなものを使用できるようにする必要があります。

void handle(BaseHandlerData *data) {
    StringData* stringData = dynamic_cast<StringData*>(...);
    // handle your string data here ...
}

予想されるデータ型に安全にキャストします。

ジェラルド

于 2012-04-10T14:54:47.193 に答える
1

さて、これがブースト::anyを使用してデータ型へのポインタを保持する簡単なアプローチです。ただし、boost :: anyはオーバーヘッドコードを追加してパフォーマンスをわずかに低下させることに注意してください(ほとんどの場合無視できます)。代わりにboost :: spirit :: hold_anyを使用するか、型の安全性が必要ない場合はvoid*を使用することを検討してください。

class Handler {
public:
    void handle( boost::any value ) { 
        do_handle( value );
    }
private:
    virtual void do_handle( boost::any& value ) = 0;
};

template<class T>
class HandlerBase : public Handler {
private:
    void do_handle( boost::any& value ) {
        // here you should check if value holds type T*...
        handle_type( *(boost::any_cast<T*>( value )) );
    }

    void handle_type( const T& value ) = 0;
};

class StringHandler : HandlerBase<std::string> {
private:
    void handle_type( const std::string& value ) {
        // do stuff
    }
};

これで、処理された型が共通の基本クラスを持っていると想定せずに、HandlerBaseから派生した多くのハンドラークラスを記述できます。

于 2012-04-10T15:05:00.947 に答える
1

もう1つの方法は、よりC世界に向けて、unionタイプ(http://en.wikipedia.org/wiki/Union_(computer_science)#C.2FC.2B.2B)です。これにより、指定したタイプのみを渡すことができ、どのタイプも渡すことはできませんが、説明する動作のタイプがあります。

于 2012-04-10T15:24:22.353 に答える
0

DataObjectなどと呼ばれる基本クラスが必要です。すべてのデータ型(文字列、数値、その他)はDataObjectのサブクラスです。次のようにハンドルを定義します。

void Handle(DataObject *dataObject);

これは、やりたいことを行うためのはるかに安全な方法です。さらに改善するために、DataObjectは、含まれているデータの種類を知ることもできます。次に、ハンドラーは、正しいタイプのデータが送信されたことを確認できます。

于 2012-04-10T14:42:52.093 に答える
-1

できるよ

B* someB = static_cast<B*>(theVoidPointer);
于 2012-04-10T14:42:21.143 に答える