1

これが私の問題の抽象化です。

こういうものを開発したい。

class Base {
}

template<typename T>
class TypedBase : Base {

    f(const T& input);
}

ここで、基本ポインタを介してクラス TypedBase の「ファミリ」にアクセスし、f を呼び出したいと考えています。

このようなもの

Base* base_ptr;
if (condition) {
  base_ptr = new TypedBase<double>();
} else {
  base_ptr = new TypedBase<int>();
}

// Int and double are just examples to get the idea
// Then I Want to call

base_ptr->f(4);

これはコンパイルされません。

空の仮想関数 f() を base に追加しようとしましたが、実行時に vtable が正しい f() と f(T& input) の呼び出しを処理することを期待していましたが、次のように機能しませんでした。

class Base {
   virtual f() = 0;
}

では、どうやってそれを行うのですか?一般に、ファミリへのジェネリック ポインターを介して f(...) を呼び出すことができるジェネリック TypedBase へのポインターが必要です。何かご意見は?

もちろん、私はこれを行うことができます:

class Base {
    // Repeat for every typename
    virtual f(int& x) = 0;
    virtual f(double& x) = 0;
} 

そして、各 TypedBase はそれらの 1 つだけを実装するため、コードで動的チェックを行うことなく、実行時に型の安全性を確保できます。ただし、呼び出す関数が N 個あり、操作する型が M 個ある場合は、M*N 個の抽象関数を Base クラスに追加する必要があります。より良い解決策はありますか?

4

1 に答える 1

1

static_cast(実際の型がわかっている場合)または(キャストが成功したかどうかを確認する必要dynamic_castがある場合)正しいクラスへの基本ポインターが必要です。メソッドに何を渡すかがわかっている場合、その引数を取る型へのキャストは問題になりません。また、キャストは適切なテンプレート タイプのテンプレート メソッドで機能する必要があります。

以下はコンパイルされますか?

template <typename T>
void callF(Base *p, T input) {
  TypedBase<T> *tp = dynamic_cast<TypedBase<T>*>(p);
  if (tp) tp->f(input);
  // else throw exception or call some Base method or return error or...
}

または安全性が低い場合は、次のようにします。

static_cast<TypedBase<int>*>(base_ptr)->f(1);
于 2013-01-29T22:51:52.237 に答える