問題は次のとおりです。
1)私は次のようなクラスを持っています:
class some_class
{
public:
some_type some_value;
int some_function(double *a, double *b, int c, int d, void *e);
};
2)some_function
内で、some_values
オブジェクトのsome_class
を使用して結果を取得します。
3)だから、具体的なオブジェクトがあり、このオブジェクトへのポインターを取得したいsome_function
。
出来ますか?この関数の結果はオブジェクトの具体的なsome_fcn_ptr
に依存するため、some_value
は使用できません。
オブジェクトのsome_function
へのポインターを取得するにはどうすればよいですか?ありがとう。
typedef int (Some_class::*some_fcn_ptr)(double*, double*, int, int, void*);
少なくとも、それは関数へのポインタだけではありません。
メンバー関数は、このクラスのすべてのインスタンスに共通です。すべてのメンバー関数には、暗黙の(最初の)パラメーター-this
があります。特定のインスタンスのメンバー関数を呼び出すには、このメンバー関数とこのインスタンスへのポインターが必要です。
class Some_class
{
public:
void some_function() {}
};
int main()
{
typedef void (Some_class::*Some_fnc_ptr)();
Some_fnc_ptr fnc_ptr = &Some_class::some_function;
Some_class sc;
(sc.*fnc_ptr)();
return 0;
}
詳細はこちら C++ FAQ
Boostを使用すると、次のようになります(C++ 11は同様の機能を提供します)。
#include <boost/bind.hpp>
#include <boost/function.hpp>
boost::function<void(Some_class*)> fnc_ptr = boost::bind(&Some_class::some_function, _1);
Some_class sc;
fnc_ptr(&sc);
C++ 11のラバ:
#include <functional>
Some_class sc;
auto f = [&sc]() { sc.some_function(); };
f();
// or
auto f1 = [](Some_class& sc) { sc.some_function(); };
f1(sc);
関数またはメソッドの両方をパラメーターとして使用できる、何らかの種類のラッパーを作成できます。
関数を起動するために次のクラスを使用しました(SDLプログラムで使用されました)。
class CallbackFunction {
public:
// Constructor, copy constructor and destructor
virtual int execute( SDL_keysym* keysym) const;
virtual int operator()( SDL_keysym* keysym) const;
protected:
int( *callback)( SDL_keysym*));
}
int CallbackFunction::execute( SDL_keysym* keysym) const{
return callback(keysym);
}
int CallbackFunction::operator()( SDL_keysym* keysym) const{
return callback( keysym);
}
そして、この「メソッド」の拡張:
template<class T>
class CallbackMethod : public CallbackFunction {
public:
// Constructor, copy constructor and destructor
CallbackMethod( T *object, int(T::*callback)( SDL_keysym* keysym));
int execute( SDL_keysym* keysym) const;
int operator()(SDL_keysym* keysym) const;
protected:
T *object;
int(T::*method)( SDL_keysym* keysym);
};
// Object initialization (constructor)
template<class T>
CallbackMethod<T>::CallbackMethod( T *object, int(T::*callback)( SDL_keysym* keysym)):
CallbackFunction( NULL),object(object),method(callback){
}
// Responsible for executing
template<class T>
int CallbackMethod<T>::execute( SDL_keysym* keysym) const {
return (object->*method)(keysym);
}
template<class T>
int CallbackMethod<T>::operator()( keysym) const {
return (object->*method)( keysym);
}
そして、次のように使用します:
CallbackFunction *callback;
callback = new CallbackFunction( myFunction);
callback = new CallbackMethod<A>( instanceOfA, instanceOfA::myMethod);
callback = new CallbackMethod<B>( instanceOfB, instanceOfB::myMethod);
...
callback( keysym);
私はこれとしてマクロを見つけました:
CALLBACK(object,method) new CallbackMethod<typeof(*object)>( object, &method)
本当に便利
いいえ、C++クラスメソッドへのポインタを取得することはできません(メソッドが静的に宣言されていない限り)。その理由は、クラスメソッドには常に、クラスインスタンスへのポインターthis
があるためです。しかし、ポインタを介してメソッドを呼び出す場合、そのポインタはthis
ポインタをカプセル化できず、インスタンスはアタッチされないため、この動作は無効です。
正確にあなたが要求したものではありませんが、C++ 11を使用できる場合、それでも次のことがニーズに合うかもしれません(未テスト):
std::function<int(double*, double*, int, int, void*)>
some_function_of(Some_class& obj)
{
return [&](double* a, double* b, int c, int d, void* e){
return obj.some_func(a, b, c, d, e); };
}
Boost ライブラリを使用しました。コードに「boost/bind.hpp」を含めました。次に、「fn」という名前のメソッドを次のように定義できます
auto fn = boost :: bind(ClassName :: methodName、classInstanceName、boost :: placeholders :: _ 1);