2013-08-09 18 views
13

クラスのメンバ関数へのポインタを別の関数に渡そうとする小さなプログラムを作成しました。あなたは私を助けてくれるでしょうか、どこに間違っているのですか?クラスメンバ関数へのポインタをパラメータとして渡す

#include<iostream> 
using namespace std; 
class test{ 
public: 
     typedef void (*callback_func_ptr)(); 
     callback_func_ptr cb_func; 

     void get_pc(); 

     void set_cb_ptr(void * ptr); 

     void call_cb_func(); 
}; 
void test::get_pc(){ 
     cout << "PC" << endl; 
} 
void test::set_cb_ptr(void *ptr){ 
     cb_func = (test::callback_func_ptr)ptr; 
} 
void test::call_cb_func(){ 
      cb_func(); 
} 
int main(){ 
     test t1; 
      t1.set_cb_ptr((void *)(&t1.get_pc)); 
     return 0; 
} 

コンパイルしようとすると次のエラーが発生します。

error C2276: '&' : illegal operation on bound member function expression 
+0

私はいつもhttp://www.newty.de/fpt/index.htmlが非常に便利だと分かります。 – arne

+2

メンバ関数は関数ではありません。必要な型は 'void(test :: *)(void *)'です... –

+1

Kerrek SBが正しいです。しかし、異なるクラスやインスタンスに対して同じメンバを呼び出すつもりなら、継承と仮想を考えるべきです... –

答えて

19

void*に関数ポインタをキャストすることはできません。

あなたはメンバ関数を指すように関数ポインタをしたい場合は、さらにあなたは、例えば、結合したメンバ関数への関数ポインタを宣言することはできません

ReturnType (ClassType::*)(ParameterTypes...) 

ようなタイプを宣言する必要があります

func_ptr p = &t1.get_pc // Error 

代わりに、あなたがこのようなアドレスを取得する必要があります。あなたはメンバ関数を指す関数ポインタへの呼び出しを行うとき

func_ptr p = &test::get_pc // Ok, using class scope. 

最後に、あなたはクラスのインスタンスでそれを呼び出す必要があります関数がのメンバーであること。例えば:

(this->*cb_func)(); // Call function via pointer to current instance. 

は、ここで適用されたすべての変更との完全な例です:SNPSの答えに加えて

#include <iostream> 

class test { 
public: 
    typedef void (test::*callback_func_ptr)(); 
    callback_func_ptr cb_func; 
    void get_pc(); 
    void set_cb_ptr(callback_func_ptr ptr); 
    void call_cb_func(); 
}; 

void test::get_pc() { 
    std::cout << "PC" << std::endl; 
} 

void test::set_cb_ptr(callback_func_ptr ptr) { 
    cb_func = ptr; 
} 

void test::call_cb_func() { 
    (this->*cb_func)(); 
} 

int main() { 
    test t1; 
    t1.set_cb_ptr(&test::get_pc); 
    t1.call_cb_func(); 
} 
+1

void test :: call_cb_func(){(this - > * cb_func)();} オブジェクト内からポインタで関数を呼び出す必要はありません。したがって、この例の「これ」はまったく役に立たない説明です。 C++は、おそらく16進数以外の非人間的な構文であることを考えると、他のオブジェクトから関数を呼び出す方法を単純に推測することはできません。 –

2

、あなたもラムダを保存するためにC++ 11からfunction wrapperを使用することができます関数:

#include <iostream> 
#include <functional> 

class test 
{ 
    public: 
    std::function<void()> Func; 
    void get_pc(); 
    void call_cb_func(); 
    void set_func(std::function<void()> func); 
}; 

void test::get_pc() 
{ 
    std::cout << "PC" << std::endl; 
} 

void test::call_cb_func() 
{ 
    Func(); 
} 

void test::set_func(std::function<void()> func) 
{ 
    Func = func; 
} 

int main() { 
    test t1; 
    t1.set_func([&](){ t1.get_pc(); }); 
    t1.call_cb_func(); 
} 
関連する問題