Zeiger auf Methoden als Parameter
-
Hiho,
ich habe folgendes Problem:
ich habe mehrere Methode, die an sich fast das gleiche machen. Es gibt nur 2 Unterschiede: 2 verschiedene Objekttypen und bei einem Typen wird in der Methode jeweils eine andere Methode aufgerufen. Da die halt so ähnlich sind, wollte ich das gerne zu einer Methode zusammen fassen.
So verschiedene Typen ist ja kein Problem: templates!
Aber ich weis nicht so recht, wie ich die Methoden als Parameter übergeben soll.Das habe ich bisher:
typedef double (*getValue)(double); // template<class T> bool drawData(T& obj,typename T::getValue methode,CStaticOGL& statControl); ... // template<class T> bool CDialogFunction::drawData(T& obj,typename T::getValue methode,CStaticOGL& statControl) { try { vector<Vertex2d> points; points.reserve((int)(m_dtSpline * 361.0)); float minValue = (float)obj.*methode(degreeToRad(0.0)); usw.Das haut aber noch nicht so richtig hin. Die Methoden sind in den eigentlichen Klassen dann auch zusätzlich noch const. Inwieweit muss dass denn dann mit einfließen?
-
*push*
-
Wenn es sich um Methoden handelt, ist
Pellaeon schrieb:
typedef double (*getValue)(double);schon mal nicht richtig, denn das ist ein Funktionszeiger. Methodenzeiger deklariert man folgendermaßen:
typedef [modifiers] <returnvalue> (<class>::*<name>) (<arguments>) [const];Wie man sieht, ist hier die Angabe einer Klasse vonnöten, das typedef ist also typabhängig. Da es keine typedef-Templates gibt, muß man sich hier mit einer Struktur behelfen:
template <class T> struct getvaluemethod_t { typedef double (T::*type) (double) const; };Und schon kannst du dein Funktionstemplate schreiben:
class MyClass { public: double getValue (double warumUebernimmtEineGetValueFunktionBlossEinenParameter) const { return 2.0; } }; template <class T> void someFunctionTemplate (const T& obj, typename getvaluemethod_t <T>::type getValueFunc) { (obj.*getValueFunc) (12.34); } ... MyClass mc; someFunctionTemplate (mc, &MyClass::getValue);Wenn die Adresse der Funktion bereits zur Kompilierzeit bekannt ist, ist allerdings die folgende Variante besser:
template <class T, typename getvaluemethod_t <T>::type GetValueFunc> void anotherFunctionTemplate (const T& obj) { (obj.*GetValueFunc) (56.78); } ... MyClass mc; anotherFunctionTemplate <MyClass, &MyClass::getValue> (mc);Hier wird die Adresse der Funktion als Template-Argument übergeben, kann also statisch gelinkt werden.
-
THX, genau das habe ich gesucht. Wär evtl was fürs FAQ?