クラスメンバ関数を呼び出す標準ライブラリを使用しない以下の例を書きました。これは期待通りに機能しますが、より一般的なものにしたいと思います。これは、8ビットマイクロコントローラを備えた組み込みシステム向けです。私は、この種のアーキテクチャにC++を使用するかどうかの議論を誘発したくありません。stlと動的メモリ割り当てを持たないメンバ関数クラス
コードは次のように動作します。クラスメンバ関数または関数にvoidポインタを使用することはできません。単一の関数に対してvoidポインターを使用することは可能ですが、これは明確な動作ではありません。
この場合、クラスメンバーを呼び出すために静的関数を使用します。メソッド呼び出し側関数は、静的テンプレート関数であり、オブジェクト型とメンバ関数ポインタをテンプレート引数として受け取ります。
bind関数は、オブジェクトポインタをvoidポインタとして格納し、クラス内のcallingFunctionを特定の静的メソッドに設定します。呼び出しが()演算子で行われるとき、callFunctionポインターは特定のオブジェクトとすべてのパラメーターで呼び出されます。
これはすべて期待どおりに動作し、バリデーショナルテンプレートのためにC++ 11を有効にしてコンパイルできます。私の意図は、APIをより快適にすることです。 f.bind(& t)を使用すると、少し時間がかかるようですが、これを行うにはもっと良い方法はわかりません。何か案は?
もう1つのポイントは、クラスの一部ではない関数を格納することです。
#include <iostream>
class testclass {
public:
virtual char test(void){
return '.';
}
};
class testclass2 : public testclass{
public:
char test(void){
return '@';
}
};
template<typename signature>
class Function;
template<typename TReturn, typename ...TParam>
class Function<TReturn(TParam...)> {
public:
template<typename TObject, TReturn (TObject::*TMethod)(TParam...)>
void bind(TObject *obj){
this->obj = obj;
this->callingFunction = &methodCaller<TObject, TMethod>;
}
TReturn operator()(TParam... params){
return callingFunction(this->obj, params...);
}
private:
void *obj;
TReturn (*callingFunction)(void *obj, TParam...);
template<typename TObject, TReturn (TObject::*TMethod)(TParam...)>
static TReturn methodCaller(void *obj, TParam... params) {
TObject *c = static_cast<TObject*>(obj);
return (c->*TMethod)(params...);
}
};
int main(){
testclass t;
Function<char(void)> f;
f.bind<testclass, &testclass::test>(&t);
std::cout << f();
testclass2 t1 = testclass2();
f.bind<testclass, &testclass::test>(&t1);
std::cout << f();
}
どのインタフェースを使用しますか? – Jarod42
より良いインターフェースはf.bind(&t、&testclass :: test)となるでしょう – Gustavo