1

基本的に、いくつかのアルゴリズムを実行するテンプレートクラスがあり、そのアルゴリズムには、similarity(T t1, T t2)タイプTの2つのオブジェクトがどれほど類似しているかを定義するdoubleを返す関数が必要です。この類似度関数は、Tが何として定義されているかによって大きく異なるため、このクラスの呼び出し元は類似度関数を定義する必要があります。関数ポインターが正常であると仮定しますが、アルゴリズムで使用するメンバー関数として関数ポインターから関数を保存するにはどうすればよいですか?

つまりsimilarity(T t1, T t2)、クラスのコンストラクターを渡し、それをクラス全体のメンバー関数として呼び出せるようにしたいのです。それ、どうやったら出来るの?ありがとう

4

4 に答える 4

2

実行時にクラスにメンバー関数を追加することはできません。

関数ポインタを介して、提供された関数を呼び出すメンバー関数を作成できます。

class MyClass {
    typedef double (*similarity_fn_type)(T t1, T t2);
    similarity_fn_type similarity_fn;
  public:
    MyClass(similarity_fn_type ptr) : similarity_fn(ptr) {}
    double similarity(T t1, T t2) {
        return similarity_fn(t1, t2);
    }
};

または、メンバーを公開することもできます。similarity_fnそれを呼び出すための構文は、それをメンバー関数のように見せますが、それが優れたカプセル化であるとは思わないかもしれません。

于 2012-07-24T15:27:07.583 に答える
1

これを行うには、よりクリーンでオブジェクト指向の方法があります。それらの1つは、JavaがComparatorクラスとの比較を再実装できるようにする方法と同様に、その関数を使用してオブジェクトを渡すことです。これは、の実装ごとに基本クラス(その機能は純粋に仮想として機能する)とサブクラスを作成することを意味しsimilarity()ます。

あなたの場合、比較とハッシュのための関数を実装するためにC++11が採用するソリューションがより役立つかもしれません。これには、特別な関数オブジェクトの作成が含まれます。例については、 std::lessおよびstd::hashを参照してください。

于 2012-07-24T15:35:06.973 に答える
0

コレクションを反復処理するプロセスを抽象化するのと同じようなことをします。述語を使用して、実際の検索条件を指定します。

void MyClass::Copy(Class &destination, const Class &source, const std::function<bool (const Effect&)> &predicate)
{
    for (size_t i = 0; i < Effect::Max; ++i)
    {
        const Effect *const pEffect = source.GetEffect(i);
        if (predicate(*pEffect))
        {
            // Do something
        }
    }
}

void MyClass::CopyInner(Class &destination, const Class &source)
{
    this->Copy(destination, source, [](const Effect &effect)
    {
        return effect.IsInner();
    });
}

:これはいくつかのC++11機能を使用します。

于 2012-07-24T15:30:35.837 に答える
0

const適切なタイプの関数ポインタメンバーを定義します。

typedef double(*Similarity)(T, T);
const Similarity similarity;

コンストラクターにそのタイプの関数を受け入れさせます。

Class(Similarity f) : similarity(f) {}

次に、関数を呼び出すことは、通常のメンバー関数を呼び出すことと同じ構文になります。

frobnicate(similarity(foo, bar));

また、メンバーがの場合はpublic、であるため、下から変更することはできませんconst

于 2012-07-24T15:34:30.067 に答える