2017-06-01 4 views
1

クラス 'Caller'からクラス 'A'と 'B'のいくつかのメソッドを呼びたいと思います。私は別のメソッドを呼びたいので、関数ポインタを使う必要があります。関数ポインタを使ってオブジェクトのメソッドを呼び出す方法は?

私のメソッドが呼び出されますが、そこからメンバ変数にアクセスしようとすると、プログラムがクラッシュします( 'program.exeは動作を停止しました')。

どうしたのですか?

#include <iostream> 

using namespace std; 


template <class T> 
class Caller 
{ 
    typedef void (T::*myFunc)(int); 
    public: 
     Caller(T* obj, myFunc fp) 
     { 
      f = fp; 
     } 
     void invoke(int foobar) 
     { 
      (o->*f)(foobar); 
     } 
    private: 
     myFunc f; 
     T* o; 
}; 

class A 
{ 
    public: 
     A() : n(0) {} 
     void foo(int bar) 
     { 
      cout << "A::foo called (bar = " << bar << ", n = " << n << ")" << endl; // the crash occurs here, and 'this' equals 0 at this point 
     } 
     void setNum(int num) 
     { 
      n = num; 
     } 
    private: 
     int n; 
}; 

class B 
{ 
    public: 
     B() : n(0) {} 
     void fooo(int bar) 
     { 
      cout << "B::fooo called (bar = " << bar << ", n = " << n << ")" << endl; // same here if I call B::fooo first 
     } 
     void setNum(int num) 
     { 
      n = num; 
     } 
    private: 
     int n; 
}; 

int main() 
{ 
    A myA; 
    B myB; 

    myA.setNum(128); 
    myB.setNum(256); 

    Caller<A> cA(&myA, &A::foo); 
    Caller<B> cB(&myB, &B::fooo); 

    cA.invoke(10); 
    cB.invoke(20); 

    return 0; 
} 

ありがとうございます。

編集:私はVS2017を使用して、私はコンパイラのエラーを取得せずに私のプログラムを構築することができます。

答えて

1

私の方法は、

あなたCalleroポインタにobjを渡さ割り当てるのを忘れているので...と呼ばれるが、私はそれからのメンバ変数にアクセスしようとすると、私のプログラムがクラッシュします:

template <class T> 
class Caller 
{ 
    typedef void (T::*myFunc)(int); 
public: 
    Caller(T* obj, myFunc fp) 
    { 
     o = obj; // << == you need this! 
     f = fp; 
    } 
    void invoke(int foobar) 
    { 
     (o->*f)(foobar); 
    } 
private: 
    myFunc f; 
    T* o; 
}; 

また、一般的にはmember initializer listsを使用することをお勧めします:

Caller::Caller(T* obj, myFunc fp) : o(obj), f(fp) 
{ 
} 
+0

ありがとうございました。今それは魅​​力のように動作します!私はそんなに愚かな間違いをしたとは思っていません...そしてあなたの助言に感謝します。私は私のメソッドだけを保存して呼び出すことができるのだろうか?そのオブジェクトなしでは意味しません。 – winapiwrapper

+1

オブジェクトなしで非静的メソッドを呼び出すことはできません。単純に意味がありません。静的にすると、他のメンバー以外の関数と同じように呼び出すことができます。 – Pavel

+0

さて、私はそれを今得ます。非常にパベルありがとうございます。 – winapiwrapper

関連する問題