4

次のクラス階層は、抽象リソース ハンドラーとリソース階層を表しています。どちらも基本クラスとしてインターフェイスを持っています。ここで、これらのインターフェースの下に複数の特定のリソース システムを実装できるシステムを作成することを想像してください。これはほんの一例です。特定のメイン クラスは、stuff から派生したリソースを作成します。作成されたリソースが基本インターフェイスに渡されると、基本リソース クラスへのポインターとして渡されますが、特定のリソースを処理し、その特定の属性にアクセスしたいと考えています。

二重発送については知っていますが、この場合はうまくいかないと思います。RTTI と dynamic_casts を防止したいと考えています。そのような場合を処理するための提案はありますか?

class resource;

class main_resource_handler
{
public:
   virtual resource* create_resource() = 0;
   virtual void do_some(resource* st) = 0;
};

class resource
{
};

class specific_resource : public resource
{
public:
    int i;
};

class specific_resource_handler : public main_resource_handler
{
public:
    stuff* create_resource) {
        return new specific_resource);
    }
    void do_some(resource* st) {
        // in here i want to work with specific resource
    }
    void do_some(specific_resource* st) {
        // i want to get here
    }
}

main_resource_handler* handler = new specific_resource_handler();
resource* res = handler->create_resource();
handler->do_some(res); /// here
4

4 に答える 4

1

あなたは正しい質問をしていないと思います。

あなたが求めていることをするために必要なのは、これを追加することだけです:

template<typename T>
class helper : public main_resource_handler
{
public:
   virtual resource* create_resource() { return new T; }
   virtual void do_some(resource* st) { do_some_specific(static_cast<T*>(st)); }
private:
   virtual void do_some_specific(T* st) = 0;
};

そしてこれを変更します:

class specific_resource_handler : public helper<specific_resource>
{
private:
   virtual void do_some_specific(T* st) { ... }
}

常に正しいタイプのハンドラーでstatic_cast呼び出すことが保証できる場合にのみ、 は安全です。do_someしかし、それが適切な種類のハンドラーであることが既にわかっている場合は、基本クラスのメソッド呼び出しを行う必要はありません。resourceしたがって、おそらくあなたが望むのは、正確な型を知らずにある種の を取得し、それを適切なハンドラーに渡すことです。それはもっとトリッキーです...

于 2010-02-28T17:19:33.000 に答える
0

Curiously recurring template パターンが探しているものであるかどうか疑問に思います。このトピックについては、stackoverflow に既にスレッドがあります。

于 2010-02-28T16:59:32.220 に答える
0

リソースとハンドラーの両方が必要な理由がわかりません-カプセル化される何かへの追加のカップリングを公開しているようです。create resource が、クライアントがメソッドを直接呼び出すことができるリソースを返しただけであれば、問題は存在しません。

安全が必要な場合は、リソースを作成したハンドラのアドレスをリソースに記憶させてから、 で確認してくださいdo_some(resource* st)。リソースが現在のハンドラーによって作成され、ハンドラーが特定の種類のリソースしか作成できない場合は、それをキャストして特定の関数を呼び出しても安全です。ただし、上記のように、関数がリソース上の単なる仮想関数である場合、定義によりタイプ セーフになります。

于 2010-02-28T17:18:34.397 に答える
0

私はあなたがこれを探しているかもしれないと思います:

http://www.artima.com/cppsource/cooperative_visitor.html

于 2010-04-13T16:36:42.673 に答える