Also Funktionspointer werden wie gefolgt deklariert.
1
classA
2
{
3
public:intdoSomething(unsignedintpara);
4
private:
5
intsum;
6
7
8
};
9
10
typedefint(A::ptr*)(unsignedint);
11
12
ptr=&A::doSomething;//zeigt auf Adresse von Funktion doSoemthing
Mein Problem:
Die Klasse beinhaltet den Wert sum, welcher durch den Parameter von der
Methode verändert wird. Von dieser Klasse werden viele Objekte angelegt.
Meine Frage: Wird durch die obige Zuweisung des Funktionspointer die
Adresse der Methode des erzeugten Objekts oder.... abgespeichert. D.h:
Kann ich ein Array, welches die einzelnen Funktionspointer enthält,
anlegen, wo sie der Reihenfolge von der Erzeugung der Objekte angeordnet
sind oder muss eine Bindung(Funktor) erfolgen?
Beim Gebrauch von Funktionspointern gibt es keinen this-Pointer, also
ist kein Zugriff auf Elemente eines zugehörigen Objektes möglich.
Deswegen sind Memberfunktionen einer Klasse, auf die mit
Funktionspointern zugegriffen werden soll, auch als static zu
deklarieren.
Sollte es davon abweichende Möglichkeiten in C++ zu geben, würde ich
gerne wissen, wie das gehen soll.
Rufus Τ. Firefly schrieb:> Beim Gebrauch von Funktionspointern gibt es keinen this-Pointer, also> ist kein Zugriff auf Elemente eines zugehörigen Objektes möglich.> Deswegen sind Memberfunktionen einer Klasse, auf die mit> Funktionspointern zugegriffen werden soll, auch als static zu> deklarieren.>> Sollte es davon abweichende Möglichkeiten in C++ zu geben, würde ich> gerne wissen, wie das gehen soll.
Nur der Vollständigkeit halber:
Es geht schon. Aber blöderweise ist dann der Klassenname Teil des
Datentyps des Funktionspointers. Und damit ist das ganze dann ein wenig
witzlos.
Georg schrieb:> Also Funktionspointer werden wie gefolgt deklariert.> class A> {> public: int doSomething(unsigned int para);> private:> int sum;>>> };>> typedef int(A::ptr*)(unsigned int);>> ptr=&A::doSomething; //zeigt auf Adresse von Funktion doSoemthing
ptr ist ein Typedef, keine Variable, also eher:
1
ptrp=&A::doSomething;
> Meine Frage: Wird durch die obige Zuweisung des Funktionspointer die> Adresse der Methode des erzeugten Objekts oder.... abgespeichert. D.h:> Kann ich ein Array, welches die einzelnen Funktionspointer enthält,> anlegen, wo sie der Reihenfolge von der Erzeugung der Objekte angeordnet> sind oder muss eine Bindung(Funktor) erfolgen?
Die Bindung erfolgt beim Aufruf, z.B. so:
1
Aa;
2
a.*p(42);
Rufus Τ. Firefly schrieb:> Beim Gebrauch von Funktionspointern gibt es keinen this-Pointer, also> ist kein Zugriff auf Elemente eines zugehörigen Objektes möglich.
Richtig, aber es geht hier um einen Pointer auf eine Memberfunktion,
nicht um einen normalen Funktionszeiger.
> Sollte es davon abweichende Möglichkeiten in C++ zu geben, würde ich> gerne wissen, wie das gehen soll.
Na so wie's oben steht.
Karl Heinz Buchegger schrieb:> Nur der Vollständigkeit halber:> Es geht schon. Aber blöderweise ist dann der Klassenname Teil des> Datentyps des Funktionspointers. Und damit ist das ganze dann ein wenig> witzlos.
Wie sollte das auch sonst gehen? in der Funktion hast du ja einen
this-Pointer. Wenn das eigentliche Objekt von einem völlig anderen Typ
wäre, käme ja nur Blödsinn raus.
Was allerdings auch mit Memberzeigern geht, ist Polymporphie.
Rolf Magnus schrieb:>> Es geht schon. Aber blöderweise ist dann der Klassenname Teil des>> Datentyps des Funktionspointers. Und damit ist das ganze dann ein wenig>> witzlos.>> Wie sollte das auch sonst gehen?
Ich hasse es, das zu sagen:
So wie in C# Delegaten implementiert sind.
Das Problem ist das ich nur einen Parameter übergeben kann(keine
unterschiedlichen für die einzelnen Objektmethoden). Also gibt es
wirklich keine Möglichkeiten,Pattern,....etc wo ich auf die Methoden
über Funktionspointer ohne Refenrenzierung des Objektes zugreifen kann.
:(
Hier ist schon der Klassenname deinem Wunsch entsprechend aus dem Typ
rausgenommen. So wie ich den Ursprungsposter verstanden hab, braucht er
das aber gar nicht. Dann kann man es vereinfachen:
Da ist der Name der Klasse noch drin, aber dafür braucht man keine
Polymorphie und muß das Delegate nicht dynamisch anlegen. Die Templates
muß man halt noch ein paarmal duplizieren, da obiges nur Funktionen mit
genau einem Parameter abdeckt. Sieht erstmal kompliziert aus, aber wenn
man mal einen Header mit dem Template-Zeugs gefüllt hat, ist das nicht
mehr so wahnsinnig schlimm. Leider muß man die ganzen Parametertypen als
Template-Argumente explizit angeben.
In der nächsten C++-Version (C++0x) wird man das nicht mehr brauchen.
g++ kann's übrigens schon heute, wenn man mit -std=c++0x kompiliert. Da
vereinfacht sich main() zu folgendem:
Rolf Magnus schrieb:> template<typename R, typename P>> class Delegate> {> public:> virtual R operator()(P param) = 0;> };
Mir ist gerade noch aufgefallen, daß hier noch der virtuelle Destruktor
fehlt.