PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++: Verwendung von Funktionspointern in einer Klasse


pajofego
2008-04-08, 23:55:40
Hallo zusammen,

ich habe einen für einen Funktionspointer, der in einer Klasse zum Einsatz kommt den Typ TClassFuncDouble definiert. Im Hauptprogramm main() möchte ich eine Variable my_func_class dieses Funktionstypen folgendermaßen definieren und wie folgt verwenden:


// foward declaration
template <class T> class TClass;

typedef double *(TClass<double>::*TClassFuncDouble)(const double);

template<class T>class TClass
{
protected:
double Funktion(const double value)
{
return sin(value);
};
public:
void WeiseFunktionZu(int typ, TClassFuncDouble &funktion)
{
switch(typ)
{
case 1:
funktion = &TClassFuncDouble::Funktion;
break;
case 2:
// usw.
}
}
};

int main()
{
TClassFuncDouble my_func_class;
TClass<double> my_class;
my_class.WeiseFunktionZu(1, my_func_class);
my_func_class(3.41); // Fehlermeldung: must use .* or ->* to call pointer-to-member function in `my_func_class (...)'
}


Ich habe die Fehlermeldung zu der letzten entsprechenden Zeile geschrieben. Ich habe solche Konstrukte in Pascal stets benutzt. Konnte aber zu dieser Fehlermeldung in C++ bis heute keine passende Lösung finden...:frown: Wie müsste denn my_func_class(3.41) richtig aufgerufen werden, damit der Funktionsaufruf in TClass funktioniert?

Danke und viele Grüße,
pajofego

del_4901
2008-04-09, 00:00:35
Steht doch da, sagtmal sind die Augen schon so verklebt? Um eine Memberfunktion über einen Funktor zu callen muss man die beiden Pointer2Member Operatoren ->* und .* verwenden.

pajofego
2008-04-09, 00:10:26
Steht doch da, sagtmal sind die Augen schon so verklebt? Um eine Memberfunktion über einen Funktor zu callen muss man die beiden Pointer2Member Operatoren ->* und .* verwenden.

Ja, habe ich gelesen nur ist doch my_func_class kein Member von TClass?!?
:confused: Oder scheitere ich hier an grundlegendem Verständnis?

del_4901
2008-04-09, 00:14:36
Ja, habe ich gelesen nur ist doch my_func_class kein Member von TClass?!?
:confused: Oder scheitere ich hier an grundlegendem Verständnis?
Aha und was ist das hier:

typedef double *(TClass<double>::*TClassFuncDouble)(const double);

Ich weiß die ganzen Funktionsdefinitionen sind etwas hässlich. my_func_class ist vom Typ TClassFuncDouble. Und den hast du so wie da oben definiert.

Ich bin aber der Meinung (ohne näheres zu wissen) das du gerade in eine Sackgasse läufst. Der Code sieht schlecht wartbar/erweiterbar aus.

Zumal es ganz schön böhze ist, einfach den Zugriffsschutz für Methoden so auszuhebeln.

pajofego
2008-04-09, 00:34:43
Aha und was ist das hier:

typedef double *(TClass<double>::*TClassFuncDouble)(const double);

Ich weiß die ganzen Funktionsdefinitionen sind etwas hässlich. my_func_class ist vom Typ TClassFuncDouble. Und den hast du so wie da oben definiert.

Ich bin aber der Meinung (ohne näheres zu wissen) das du gerade in eine Sackgasse läufst. Der Code sieht schlecht wartbar/erweiterbar aus.

Zumal es ganz schön böhze ist, einfach den Zugriffsschutz für Methoden so auszuhebeln.

Ich gebe dir Recht...die Typdefinition hat mich bzw. wirft mich immer noch um. Auch wenn's jetzt peinlich wird...ich kommt nicht dahinter wie ich den Aufruf zu machen habe :mad: ich hab das Gefühl ich dreh mich im Kreis.

Momentan bin ich dabei ein größeres Stück pascal code in c++ umzuschreiben. Bin ich noch am überlegen ob ich mit Templates weitermachen sollte?

del_4901
2008-04-09, 00:44:33
Du solltest erstmal Templates nicht für solche großen Sachen nehmen. Berechne Meinetwegen die Fakultät über Templates. Das was du suchst ist warscheinlich das Strategy Pattern. Templates nimmt man eigendlich nur dann wenn es nicht anders geht, bzw. wenn man die Compilezeitoptimierung braucht. Für alles Andere sind Templates überquallifiziert.

Referenz.*Funktor()
Pointer->*Funktor()

Steht aber auch alles in der MSDN und das ist der erste Hit in Google.

pajofego
2008-04-09, 22:20:31
Hi, zum Grund warum ich Templates verwendet hatte: War eigentlich aus der Idee herausgeboren, dass man sich in pacal z.B. durch folgende Typ Definition behilft wenn man unterschiedliche Datentypen verwenden möchte:


...
type
{$IFDEF Single_}
TValue = Single;
{$ENDIF}
{$IFDEF Double_}
TValue = Double;
{$ENDIF}
...


Sicherlich hätte ich das genauso/ähnlich in C++ wie folgt lösen können:


#ifdef Single_
typedef float TValue;
#else
typedef double TValue;
#endif


Nun bin ich irgendwie auf die Idee gekommen, das ganze mittels Templates zu realisieren, d.h. ich hatte mir ein Hilfstemplate wie folgt definiert:


template<typename T> struct TValue
{
typedef T TValueType;
};


Jetzt merke ich aber, dass die Entscheidung über die Verwendung von Templates nicht so glücklich ist und eben gerade aus deinen oben aufgeführten Argumenten.

Ich muss nochmal zu meiner ersten Frage zurückkommen: Ich muss zugeben, dass mir immer noch nicht klar ist was hier in meinem Code die Referenz bzw. den Funktor darstellt.

Funktor: my_func_class
Referenz: my_class ?

Wäre: my_class.*my_func_class(...) ist ja wie ich beim Versuch dies zu kompilieren festgestellt hatte nicht richtig. :confused:

del_4901
2008-04-09, 22:44:56
Ich muss nochmal zu meiner ersten Frage zurückkommen: Ich muss zugeben, dass mir immer noch nicht klar ist was hier in meinem Code die Referenz bzw. den Funktor darstellt.

Funktor: my_func_class
Referenz: my_class ?

Wäre: my_class.*my_func_class(...) ist ja wie ich beim Versuch dies zu kompilieren festgestellt hatte nicht richtig. :confused:
Das sollte eigentlich funktionieren. Was kommt denn für ein Fehler?
Probier mal: (&my_class)->*my_func_class(...);

pajofego
2008-04-09, 23:31:06
Oh man,

bin ich jetzt beruhigt, dass ich es eigentlich schon von anfang an richtig gemacht habe, nur lies ich mich ständig von diesem Doppelfehler beirren.

Will heißen: Die Fehlermeldung lautet stets "must use .* or ->* to call pointer-to-member function in" für:

- my_class.*my_func_class(...)
- (&my_class)->*my_func_class(...)

del_4901
2008-04-09, 23:45:59
Hallo zusammen,


case 1:
funktion = &TClass::Funktion;
break;


Einen Fehler hab ich noch gefunden ich glaub zwar nicht, dass es daran lag. Was ist das denn für ein Compiler?

pajofego
2008-04-09, 23:55:21
Einen Fehler hab ich noch gefunden ich glaub zwar nicht, dass es daran lag. Was ist das denn für ein Compiler?

Hi,

meine Schuld, ist in der Orginal Source richtig...hab's hier nur falsch reinkopiert.

Benutze Mingw 3.4.5 unter Windows mit eclipse.

del_4901
2008-04-10, 00:05:23
Hi,

meine Schuld, ist in der Orginal Source richtig...hab's hier nur falsch reinkopiert.

Benutze Mingw 3.4.5 unter Windows mit eclipse.
Probier mal:
(my_class.*my_func_class)(...)
((&my_class)->*my_func_class)(...)

pajofego
2008-04-10, 00:13:57
Probier mal:
(my_class.*my_func_class)(...)
((&my_class)->*my_func_class)(...)

Yeaaaaaah! Das war's! Mensch, danke...! ;D

Wie findet man soetwas heraus...? Ich habe knappe zwei Wochen rumgedoktort bis ich den Weg hierher gegangen bin!

Fetten Dank,

Gruß
Paulo

del_4901
2008-04-10, 00:20:46
Yeaaaaaah! Das war's! Mensch, danke...! ;D

Wie findet man soetwas heraus...? Ich habe knappe zwei Wochen rumgedoktort bis ich den Weg hierher gegangen bin!

Fetten Dank,

Gruß
Paulo
MSDN lesen. http://msdn2.microsoft.com/en-us/library/k8336763.aspx
(Hat ganze 5min gedauert)
Aber mach dir nichts draus, ich hatte auch schon vergessen, dass () stärker bindet.