4

これは実際にはチェスプレイプログラム用ですが、コードが長すぎてここに投稿できないため、より単純な無関係の例を使用します。

私がこのようなオブジェクトを持っているとしましょう:

class A{
    int x1;
    int x2;
public:
    int Average(){ return (x1+x2)/2; }
};

すべてのオブジェクトのすべてのx1およびx2値のすべての平均(またはそれらへのポインター)を格納するAveragesListというベクトルが必要です。だから私はこれをやってみました:

vector<int>* AveragesList;

class A{
    int x1;
    int x2;
public:
    int Average(){ return (x1+x2)/2; }
    A(){ AveragesList.push_back(this->Average); } //trying to add pointer to member function Average() to AveragesList
};

しかし、これを試してみると、「バインドされた関数へのポインターは、関数を呼び出すためにのみ使用できます」というメッセージが表示されます。回避策はありますか?x1またはx2の値が変更されても、AveragesListの値は変更されないため、単純にx1とx2の平均値をAveragesListに入れたくありません。また、私の本はC ++クラスでパブリック変数を使用しないと言っていたので、パブリック変数を使用すべきかどうかわかりません。

4

3 に答える 3

4

C++11 より前の C++ にはクロージャを処理する組み込みの方法がないため、boost などのライブラリを使用せずに問題に対処する最も簡単な方法は次のとおりですaveragex1x2変数。x1オブジェクトを作成するときに average を適切な値に設定し、 orx2が変更されるたびに更新します。ポインターをリストに格納し、それを使用して平均にアクセスします。

これは、その場で結果を計算するほど良くありません。C++11 を使用している場合は、より良い解決策を利用できます。

#include <iostream>
#include <vector>
#include <functional>

class A{
    int x1;
    int x2;
public:
    A(int _x1, int _x2) : x1(_x1), x2(_x2) {}
    int Average(){ return (x1+x2)/2; }
    void setX1(int _x1) { x1 = _x1; }
    void setX2(int _x2) { x2 = _x2; }
};

using namespace std;

int main() {
    vector<std::function<int()>> v;
    A a1(1, 5);
    A a2(2, 8);
    v.push_back([&]{return a1.Average();});
    v.push_back([&]{return a2.Average();});
    for (int i = 0 ; i != v.size() ; i++) {
        cout << v[i]() << endl;
    }
    a1.setX1(7);
    a2.setX2(32);
    for (int i = 0 ; i != v.size() ; i++) {
        cout << v[i]() << endl;
    }
    return 0;
}
于 2012-05-31T02:37:08.820 に答える
1

「平均」の現在の値を保存したくない場合は、「A」への参照を保存しないでください。

例:

Class A{
    int x1;
    int x2;
public:
    A (int x1, int x2) { this->x1 = x1; this->x2 = x2; }
    int Average(){ return (x1+x2)/2 }
};

...

int
main (int argc, char *argv[])
{
  vector<A> averagesList;
  averagesList.push_back (new A(3, 4));
  ...
于 2012-05-31T02:32:20.980 に答える
1

あなたがしたいことをするために(私は推測しています)、関数を呼び出すために使用するオブジェクトのポインタも保存する必要があります:

#include <vector>
#include <iostream>

class A {
  int x1,x2;
public:
  int Average(){ return (x1+x2)/2; }
  A(int a, int b);
};

std::vector< A* > objectVec;
std::vector< int (A::*)() > functionPtrVec;

A::A(int a, int b):
  x1(a), x2(b) {
  objectVec.push_back(this);
  functionPtrVec.push_back(& A::Average);
}

int main() {
  A a1(1,3);
  A a2(10,20);

  for (int k=0; k<objectVec.size(); k++) {
    int (A::* memberFuncPtr)() = functionPtrVec[k];
    A*object = objectVec[k];
    std::cout << (object->*memberFuncPtr)() << std::endl;
  }
  return 0;
}

を使用pairして同じ に格納するvectorか、オブジェクトとメンバー関数ポインターの両方を格納し、()演算子を持つ独自のメンバー ファンクター クラスを定義できます。

HTH。

于 2012-05-31T02:41:21.207 に答える