Zeiger auf Klassenfunktionen
-
Hallo,
ich habe :
class A { public: int f(int a, int b); };
Nun will ich einen Zeiger auf diese Funktion als Eigenschaft an eine andere Klasse übergeben. Also schreibe ich:
class B { public: int (A::*func)(int, int); };
Soweit, so gut.
Wenn ich jetzt aber die Funktion f ändern will inint f(int a, int b=0);
(man beachte das int b=0)
... wie muß jetzt der Zeiger aussehen?int (A::*func)(int, int=0);
geht nicht.
Vielen Dank für eure Hilfe.
-
... wie muß jetzt der Zeiger aussehen?
So wie vorher. Das Hinzufügen eines Default-Parameters ändert den Typ der Funktion nicht. Er ist danach immer noch:
int (A::*func)(int, int);
Und wenn du die Funktion indirekt über den Funktionszeiger aufrufen willst, musst du auch weiterhin zwei Parameter angeben.
-
Ich will ja aber den zweiten Parameter nicht angeben müssen, darum mach ich ja die Initialisierung int b=0.
Geht das denn nicht?
-
nein, denn default parameter werden waehrend der compile time ausgewertet.
funktionspointer aber logischerweise erst zur runtime.
-
Geht das denn nicht?
Nein. Das einfachste wäre, wenn du statt eines Def-Parameters einfach Überladung einsetzen würdest.
Alternativ könnten dir binder helfen. Hier mal am Beispiel boost::function + boost::bind.
#include <boost/bind.hpp> #include <boost/function.hpp> #include <iostream> class A { public: void func(int i, int j= 0) { std::cout << i << " " << j << std::endl; } }; class B { public: B(void (A::*func)(int, int), A* p) : func_(boost::bind(func, p, _1, 0)) {} void call() { func_(17); } private: boost::function1<void, int> func_; }; int main() { A a; B b(&A::func, &a); b.call(); }
Das entspricht aber natürlich nicht mehr einem Defaultparameter.
Alternativ geht natürlich auch sowas:
template <class R, class T, class A, class A2> struct MemFun2Def2 { public: MemFun2Def2(R(T::*fun)(A, A2), A2 a2) : fun_(fun) , a2_(a2) {} R operator()(T* o, A a1) { return (o->*fun_)(a1, a2_); } R operator()(T* o, A a1, A2 a2) { return (o->*fun_)(a1, a2); } private: R(T::*fun_)(A, A2); A2 a2_; }; class A { public: int func(int i, int j= 0) { std::cout << i << " " << j << std::endl; return 0; } }; class B { public: B(int (A::*func)(int, int)) : func_(func, 0) {} void call() { A a; func_(&a, 17); func_(&a, 17, 23); } private: MemFun2Def2<int, A, int, int> func_; }; int main() { B b(&A::func); b.call(); }
Naja, aber ich denke Überladung wäre hier wirklich das beste.
-
hallo,
boost::bind is nicht anders als ne klasse die function, memberfunction pointer usw verwaltet...ist ein allgemeinerer Ersatz für Funktionszeiger?auf deren homepage steht:
boost::bind is a generalization of the standard functions std::bind1st and std::bind2nd. It supports arbitrary function objects, functions, function pointers, and member function pointers, and is able to bind any argument to a specific value or route input arguments into arbitrary positions. bind does not place any requirements on the function object; in particular, it does not need the result_type, first_argument_type and second_argument_type standard typedefs.was sind arbitrary function objects, das wort höre ich zum ersten mal;-)?
thx
-
funktionsobjekte, die einen Parameter haben.
-
was zählt bei dir alles als funltionsobjekt? meinst du diesen _1 param?
cu