1
#include <iostream>
using namespace std;

class B
{
public:
  int getMsg(int i)
  {
    return i + 1;
  }
};

class A
{
  B b;
public:
  void run()
  {
    taunt(b.getMsg);
  }

  void taunt(int (*msg)(int))
  {
    cout << (*msg)(1) << endl;
  }
};

int main()
{
  A a;
  a.run();
}

上記のコードには、クラス A 内にクラス B があり、クラス A には関数を引数として取るメソッド taunt があります。クラス B の getMsg は taunt に渡されます...上記のコードは次のエラー メッセージを生成しました:「エラー: 'A::taunt()' の呼び出しに一致する関数がありません」

上記のコードのエラー メッセージの原因は何ですか? 何か不足していますか?

アップデート:

#include <iostream>
using namespace std;

class B
{
public:
  int getMsg(int i)
  {
    return i + 1;
  }
};

class A
{
  B b;
public:
  void run()
  {
    taunt(b.getMsg);
  }

  void taunt(int (B::*msg)(int))
  {
    cout << (*msg)(1) << endl;
  }
};

int main()
{
  A a;
  a.run();
}

t.cpp: メンバー関数 'void A::run()': 19 行目: エラー: 'A::taunt()' の呼び出しに一致する関数がありません -Wfatal-errors によりコンパイルが終了しました。

(*msg)(int) を (B::*msg)(int) に変更した後も同じエラーが発生します

4

3 に答える 3

2

b.getMsgメンバーへのポインターを形成する正しい方法ではありません。必要&B::getMsgです。

(*msg)(1)メンバーへのポインターを介して関数を呼び出す正しい方法ではありません。たとえば、関数を呼び出すオブジェクトを指定する必要があります (一時的なものを使用) (B().*msg)(1)

于 2012-05-04T19:15:04.120 に答える
0

これは VS 2010 で機能します。出力はすべての行で同じです。

#include <iostream>
#include <memory>
#include <functional>

using namespace std;
using namespace std::placeholders;

class A
{
public:
    int foo(int a, float b)
    {
        return int(a*b);
    }
};

int main(int argc, char* argv[])
{
    A temp;

    int x = 5;
    float y = 3.5;

    auto a = std::mem_fn(&A::foo);
    cout << a(&temp, x, y) << endl;

    auto b = std::bind(a, &temp, x, y);
    cout << b() << endl;

    auto c = std::bind(std::mem_fn(&A::foo), &temp, _1, y);
    cout << c(5) << endl;
}

基本的にstd::mem_fn、メンバー関数の呼び出し可能なオブジェクトを取得するために使用し、その後std::bind、オブジェクト ポインター自体を含む追加のパラメーターをバインドする場合に使用します。必要に応じて、オブジェクトへの参照もカプセル化する方法があると確信してstd::refいます。_1また、バインドで一部のパラメーターを指定し、他のパラメーターを指定しない別の方法として、転送マーカーも含めました。すべてに同じパラメーターを使用したいが、異なるオブジェクトで機能させる場合は、クラスインスタンス以外のすべてを指定することもできます。君による。

メンバー関数を認識して使用したい場合はboost::bind、すべてを 1 行にまとめて少し短くすることauto e = boost::bind(&A::foo, &temp, x, y)もできます。

于 2012-05-04T20:13:14.280 に答える
0

OOP でこのようなことを行う正しい方法は、インターフェイスを使用することです。そのため、インターフェイスを定義して B クラスに実装した後、このインターフェイスを実装するインスタンスのポインターをクラス A のメソッドに渡すだけです。

class IB{
public:
 virtual void doSomething()=0;
};

class B: public IB{
public:
 virtual void doSomething(){...}
};

class A{
public:
 void doSomethingWithB(IB* b){b->doSomething();}
};
于 2012-05-04T19:18:43.117 に答える