🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.c++
12 messages
12 total messages Started by Andreas Sedlmayr Thu, 16 Nov 1995 18:13
Funktionszeiger auf Klassenmethoden
#804
Author: Andreas Sedlmayr
Date: Thu, 16 Nov 1995 18:13
41 lines
1806 bytes
Hallo C++ Freaks!

Ich habe folgendes Problem. Eine Klasse "CCalculate" enthält mehrere
gleich aufgebaute Funktionen des Formats:
	long double (CCalculate::*fnftldOperation) (long double);
Ich möchte den Funktionszeiger "fnftldOperation" die entsprechende
mathematische Funktion (innerhalb d. Klasse) zuweisen, 
	fnftldOperation=Methodenname
so daß ich z.B. in einer Schleife mehrere Funktionsaufrufe über den
Funktionszeiger durchführen kann.
Mein versuchter Funktionsaufruf sieht wie folgt aus:
	long double ftErg = fnftldOperation(ftZahl);
bzw:	long double ftErg = *(fnftldOperation)(ftZahl);

Der Compiler (Visual C++) mekert aber: error C2064: term does not
evaluate to a function

Meine Frage:
Geht das prinzipiell nicht, oder mache ich syntaktisch etwas falsch?

falls das geht, noch einen Schritt weiter:

Läßt sich ein solcher Methodenzeiger einer Windows-Funktion übergeben
(möglicherweise gecastet):
		FARPROC MakeProcInstance(lpProc, hinst)

		FARPROC lpProc;	/* address of function	*/
		HINSTANCE hinst;	/* instance to bind to function	*/

lpProc sei ein Methodenzeiger


Vielen Dank für alle Beiträge zu diesem Thema



Ciao, Andi
                     
                           andreas sedlmayr - munich - germany
                           EMail: Sedl@lrz.fh-muenchen.de
                           (or 01949888@fhmrz4.rz.fh-muenchen.de)
Re: Funktionszeiger auf Klassenmethoden
#817
Author: Holger Vogelsang
Date: Fri, 17 Nov 1995 09:13
33 lines
1830 bytes
>Hallo C++ Freaks!
>
>Ich habe folgendes Problem. Eine Klasse "CCalculate" enthält mehrere
>gleich aufgebaute Funktionen des Formats:
>	long double (CCalculate::*fnftldOperation) (long double);
>Ich möchte den Funktionszeiger "fnftldOperation" die entsprechende
>mathematische Funktion (innerhalb d. Klasse) zuweisen, 
>	fnftldOperation=Methodenname
>so daß ich z.B. in einer Schleife mehrere Funktionsaufrufe über den
>Funktionszeiger durchführen kann.
>Mein versuchter Funktionsaufruf sieht wie folgt aus:
>	long double ftErg = fnftldOperation(ftZahl);
>bzw:	long double ftErg = *(fnftldOperation)(ftZahl);
>
>Der Compiler (Visual C++) mekert aber: error C2064: term does not
>evaluate to a function
>
>Meine Frage:
>Geht das prinzipiell nicht, oder mache ich syntaktisch etwas falsch?

Es lassen sich nur die Adressen STATISCHER Methoden ermitteln.
Auf welches Objekt soll denn sonst auch die spaeter ueber einen
Zeiger aufgerufene Methode wirken ?

Holger

-----------------------------------------------------------------
Holger Vogelsang
Institut fuer Mikrorechner und Automation, Universitaet Karlsruhe 
Haid-und-Neu-Strasse 7,  D-76131 Karlsruhe
Tel.: +49+721 6083170, Fax : +49+721 661732
WWW: http://www-ima.ira.uka.de/mitarbeiter/vogelsan/
Re: Funktionszeiger auf Klassenmethoden
#871
Author: Roland Minde
Date: Tue, 21 Nov 1995 14:15
36 lines
1557 bytes
This is a multi-part message in MIME format.

---------------------------------43232605012758
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=iso-8859-1

Hallo Andi

Natürlich kann man auch Member-Function-Pointer haben.
Der Aufruf einer Memberfunktion geht aber stets nur mit einem Objekt.
Siehe nachfolgendes Beispiel, ausprobiert nach Beispielen
aus Ellis, Stroustrup; The Annotated C++ Reference Manual; §8.1c

---------------------------------43232605012758
Content-Transfer-Encoding: 7bit
Content-Type: zz-application/zz-winassoc-C

#include <iostream.h>
struct S
{
  int f(char*);
  int i;
  S(): i(13)  {}
};
int S::f(char* st)  { cout <<st <<endl;  return i; }
main()
{ S s;
  int* ip =&s.i;        // ip points to s's member i
  int S::* sip =&S::i;  // sip get offset of `i' in an S
  cout <<"Use ip=" <<*ip  <<endl;
  //cout <<"Use sip=" <<*(&s+sip);
  int (S::*pmf)(char*) =&S::f;  // Pointer to member Function
  int j =(s.*pmf)("hallo");
}

---------------------------------43232605012758--
Re: Funktionszeiger auf Klassenmethoden
#901
Author: Olaf Kock
Date: Sun, 26 Nov 1995 00:00
21 lines
968 bytes
Roland.Minde@cgk.sni.de wrote
[..]
> Siehe nachfolgendes Beispiel, ausprobiert nach Beispielen
> aus Ellis, Stroustrup; The Annotated C++ Reference Manual; §8.1c
[..]
> main()
> { S s;
>   int* ip =&s.i;        // ip points to s's member i
>   int S::* sip =&S::i;  // sip get offset of `i' in an S
>   cout <<"Use ip=" <<*ip  <<endl;
>   //cout <<"Use sip=" <<*(&s+sip);
>   int (S::*pmf)(char*) =&S::f;  // Pointer to member Function
>   int j =(s.*pmf)("hallo");
> }

Ist es das, was manchmal den Eindruck erweckt, C/C++ sei eine Write-Only- 
Sprache? ;-)

Olaf
--
  ln /dev/null /dev/www
Re: Funktionszeiger auf Klassenmethoden
#915
Author: Karl-Heinz Krause
Date: Wed, 29 Nov 1995 16:28
26 lines
1435 bytes
Am 26. Nov. 1995 schrieb Olaf Kock (olaf@rupert.shnet.org):

> Roland.Minde@cgk.sni.de wrote
> [..]
> > Siehe nachfolgendes Beispiel, ausprobiert nach Beispielen
> > aus Ellis, Stroustrup; The Annotated C++ Reference Manual;  8.1c
> [..]
> > main()
> > { S s;
> >   int* ip =&s.i;        // ip points to s's member i
> >   int S::* sip =&S::i;  // sip get offset of `i' in an S
> >   cout <<"Use ip=" <<*ip  <<endl;
> >   //cout <<"Use sip=" <<*(&s+sip);
> >   int (S::*pmf)(char*) =&S::f;  // Pointer to member Function
> >   int j =(s.*pmf)("hallo");
> > }

> Ist es das, was manchmal den Eindruck erweckt, C/C++ sei eine Write-Only- 
> Sprache? ;-)

Wieso? Das ist doch sehr übersichtlich! Vor allem weil es so schön kurz
ist. Es paßt in einen Bereich von 9 Zeilen à 80 Zeichen, kann also mit
einem Blick erfaßt werden. Wenn ich da an MODULA denke ...


Karl-Heinz Krause
Re: Funktionszeiger auf Klassenmethoden
#1153
Author: Jens von Pilgrim
Date: Tue, 02 Jan 1996 12:44
34 lines
1338 bytes
Sedl@lrz.fh-muenchen.de (Andreas Sedlmayr) will Funktionszeiger auf
Methoden verwenden.
Dies waere, wenn es funktionieren wuerde toll (z.B. um in GUI-Systemem
Fenster direkt mit Event-Handler-Methoden zu verbinden). Aber:
Es KANN NICHT funktionieren: Wo kaeme den bei einem Methodenaufruf
ueber Zeiger der THIS-Pointer her?????? Und den braucht die Methode
doch unbedingt, Bsp:

  class X 
  {
    X(int inZahl) { x = inZahl; };

     int method() {return x } ;

     int x;
  }

  main()
  { X a(1),b(2);
    void *fptr;
  
    ... // hier wuerde der Funktionszeiger ermittelt (was nicht geht!)
  
    int c;
   c = *fptr(); // oder irgendwie so...
  
   -> wird jetzt 1 oder 2 zurueckgegeben??????????????????????

That's its, I'm sorry..... ;-(

Jens
  
     
 
Re: Funktionszeiger auf Klassenmethoden
#1160
Author: Reinhard Pfau
Date: Wed, 03 Jan 1996 12:20
50 lines
2345 bytes
Jens von Pilgrim (jpilgrim@conline.central.de) wrote:
: Sedl@lrz.fh-muenchen.de (Andreas Sedlmayr) will Funktionszeiger auf
: Methoden verwenden.
: Dies waere, wenn es funktionieren wuerde toll (z.B. um in GUI-Systemem
: Fenster direkt mit Event-Handler-Methoden zu verbinden). Aber:
Wenn du einen Blick in die OWL von Borland wirfst, wirst du genau das
finden ;-)
: Es KANN NICHT funktionieren: Wo kaeme den bei einem Methodenaufruf
: ueber Zeiger der THIS-Pointer her?????? Und den braucht die Methode
: doch unbedingt, Bsp:
Den gibt man bei Aufruf der Methode dann mit an:
(ich bastel mal an deinem Bsp rum...)

:   class X 
:   {
:     X(int inZahl) { x = inZahl; };
:      int method() {return x } ;
:      int x;
:   }

:   main()
:   { X a(1),b(2);
:     void *fptr;
        // ^^^^^^also so nicht, fptr ist ja kein Zgr auf 'ne Fkt.!!   
     void (X::*Xfptr)();  // Xfptr ist Zeiger auf Methode der Klasse X
:   
:     ... // hier wuerde der Funktionszeiger ermittelt (was nicht geht!)
//     doch, geht:
    Xfptr = &X::method;
:   
:     int c;
:    c = *fptr(); // oder irgendwie so...
  // s.o. fptr ist bei dir kein Fkt-Zgr.
:    -> wird jetzt 1 oder 2 zurueckgegeben??????????????????????
     c = a.*Xfptr(); // liefert 1
     c = b.*Xfptr(); // liefert 2
// waere 'd' Zgr auf 'X'-Instanz, dann:  'c = d->*Xfptr();'

: That's its, I'm sorry..... ;-(
: Jens

(Das Posting von Andreas habe ich leider hier nicht gesehen, daher
kann das ganze evtl. nicht zur urspr. Frage passen....)

Reinhard.  
--
 /-- Reinhard Pfau --- (ED-Pfau) --------------------------------------------\
| eMail: gz342@appl2.hrz.uni-siegen.de  |  IRC: Mubo  | no home-page         |
+----------------------------------------------------------------------------+
|  WinErr 0: "Mouse not found  - klick to continue"                          |
Re: Funktionszeiger auf Klassenmethoden
#1171
Author: Claus Faerber
Date: Thu, 04 Jan 1996 11:59
53 lines
1790 bytes
Jens von Pilgrim <jpilgrim@conline.central.de> schrieb zu
Re: Funktionszeiger auf Klassenmethoden
in Artikel <1996Jan2.133329.19321@conline.central.de> vom 02.01.96:
> Sedl@lrz.fh-muenchen.de (Andreas Sedlmayr) will Funktionszeiger auf
> Methoden verwenden.
> Dies waere, wenn es funktionieren wuerde toll (z.B. um in GUI-Systemem
> Fenster direkt mit Event-Handler-Methoden zu verbinden). Aber:
> Es KANN NICHT funktionieren: Wo kaeme den bei einem Methodenaufruf
> ueber Zeiger der THIS-Pointer her?????? Und den braucht die Methode
> doch unbedingt, Bsp:
>
>   class X
>   {
public:
>     X(int inZahl) { x = inZahl; };
>
>      int method() {return x } ;
>
>      int x;
>   }
>
>   main()
>   { X a(1),b(2);
>     void *fptr;
        Wenn schon, dann int(*fptr)();
>
>     ... // hier wuerde der Funktionszeiger ermittelt (was nicht geht!)
>
>     int c;
>    c = *fptr(); // oder irgendwie so...
>
>    -> wird jetzt 1 oder 2 zurueckgegeben??????????????????????

/*
   So gehts:
*/

void main(a)
{
        X a(1), b(2);

        int(X::* fptr)();       // die Syntax ist ...

        fptr = X::method;

        int c;

        c = a.*fptr();
}

-----------------------------------------------------------------------
Claus André Färber - claus@faerber.muc.de - http://www.muc.de/~cfaerber
-----------------------------------------------------------------------
Re: Funktionszeiger auf Klassenmethoden
#1177
Author: Karl-Heinz Krause
Date: Thu, 04 Jan 1996 19:20
58 lines
2329 bytes
Am 2. Jan. 1996 schrieb Jens von Pilgrim (jpilgrim@conline.central.de):

> Sedl@lrz.fh-muenchen.de (Andreas Sedlmayr) will Funktionszeiger auf
> Methoden verwenden.
> Dies waere, wenn es funktionieren wuerde toll (z.B. um in GUI-Systemem
> Fenster direkt mit Event-Handler-Methoden zu verbinden). Aber:
> Es KANN NICHT funktionieren: Wo kaeme den bei einem Methodenaufruf
> ueber Zeiger der THIS-Pointer her?????? Und den braucht die Methode
> doch unbedingt

Das ist eine Frage, die regelmäßig kommt. Zunächst einmal gibt es
natürlich Methodenzeiger, die so definiert werden:

	int (X::*mptr)();

die so einen Wert erhalten:

	mptr &X::method;

und die so aufgerufen werden:

	int c (a.*mptr)();

Beim Aufruf der Methode über den Zeiger wird hier das Objekt angegeben.

Das war aber in der Frage vermutlich nicht gemeint. Was man nämlich für
GUI-Programmierung braucht (und auch in anderen Fällen, in denen
Callbacks verwendet werden), sind gebundene Methoden. Das sind
Funktionszeiger, die intern die Information über eine aufzurufende
Methode und das zu benutzende Objekt enthalten. Beispiel:

class X {
    int x;
  public:
    X(int i): x(i) {}
    int method() { return x; }
};

main()
{
    X a(1), b(2);
    int (*fptr)();

    fptr .method;  // geht leider nicht in  C++ !

    int c ptr();   // entspricht einem Aufruf a.method()
}

Sowas haben die Entwickler von C++ leider nicht vorgesehen. Sie waren in
ihrem Denken wohl zu sehr auf konventionelle UNIX-ähnliche Systeme
fixiert und haben einfach beschlossen, daß man sowas nicht braucht. 

Für Callbacks braucht man sowas aber sehr wohl. Darum haben sich
Programmierer Hintertürchen ausgedacht. Leider geht sowas nicht
portabel. Einige Zeilen Assemblercode werden dazu benötigt.


Karl-Heinz Krause
Re: Funktionszeiger auf Klassenmethoden
#1241
Author: Karl-Heinz Krause
Date: Tue, 09 Jan 1996 20:38
74 lines
2948 bytes
Am 6. Jan. 1996 schrieb Claus Faerber (claus@faerber.muc.de):

> Karl-Heinz Krause <Krause@t-online.de> schrieb zu
> Re: Funktionszeiger auf Klassenmethoden
> >
> > class X {
> >     int x;
> >   public:
> >     X(int i): x(i) {}
> >     int method() { return x; }
> > };
> >
> > main()
> > {
> >     X a(1), b(2);
> >     int (*fptr)();
> >
> >     fptr = a.method;  // geht leider nicht in  C++ !
> >
> >     int c = fptr();   // entspricht einem Aufruf a.method()
> > }
> 
> Was ist damit:?

> // class X wie oben

> struct Xmethod {
>         X* object;
>         int (X::*method)();
> }

> main()
> {
>         X a(1), b(2);
>         Xmethod fptr = { a, &X::method };
>         //...
>         int c = (fptr.object)->*(fptr.method) ();
> }

Das ist keine Lösung des Problems. Sicher, hier in diesem Beispiel
funktioniert es. Es ging mir aber vor allem um folgenden Fall: Gegeben
sei eine Systemfunktion SyFu, die als Parameter einen Funktionszeiger
erwartet.

	void SyFu (int(*fptr)());

Die übergebene Funktion wird dann vom Betriebssystem bei Eintreten
bestimmter Ereignisse aufgerufen. Sowas kommt bei GUI-Programmierung
häufig vor, ebenso bei Netzwerkprogrammierung; überhaupt immer dann,
wenn auf asynchrone Ereignisse reagiert werden soll.

Ich will jetzt an SyFu eine Funktion übergeben, die die Methode "method"
für das bestimmte X-Objekt "a" aufruft. Wenn gebundene Methoden
existieren würden, wäre das einfach:

	SyFu (a.method);

Aber das geht in C++ nicht. Xmethod kann ich natürlich auch nicht
benutzen, denn SyFu erwartet einen Funktionszeiger und kein
Xmethod-Objekt. Was man also braucht ist sowas ähnliches wie ein
Xmethod-Objekt, das sich aber auch wie eine Funktion verhält.

In der Praxis benutzt man dazu folgenden Trick: Man setzt an den Anfang
eines Xmethod-Objekts einige zusätzliche Bytes, die im wesentlichen die
Maschinencodes für einen Funktionsaufruf enthalten. Dadurch wird
erreicht, daß die Adresse eines Xmethod-Objekts auch als Adresse einer
Funktion betrachtet werden kann, die beim Aufruf gerade das Gewünschte
macht, nämlich

	(fptr.object)->*(fptr.method)



Karl-Heinz Krause
Re: Funktionszeiger auf Klassenmethoden
#1243
Author: Holger Vogelsang
Date: Fri, 12 Jan 1996 10:21
17 lines
1273 bytes
>> Karl-Heinz Krause <Krause@t-online.de> schrieb zu
>> Re: Funktionszeiger auf Klassenmethoden

> .... geloescht ....

C++ unterstuetzt nur Zeiger auf STATISCHE Member-Funktionen.
In allen anderen Faellen kann nur ueber die Funktion nicht
ermittelt werden, auf welchen OBJEKT sie arbeiten soll.

Holger
 
-----------------------------------------------------------------
Holger Vogelsang
Institut fuer Mikrorechner und Automation, Universitaet Karlsruhe 
Haid-und-Neu-Strasse 7,  D-76131 Karlsruhe
Tel.: +49+721 6083170, Fax : +49+721 661732
WWW: http://www-ima.ira.uka.de/mitarbeiter/vogelsan/
Re: Funktionszeiger auf Klassenmethoden
#1247
Author: Reinhard Pfau
Date: Fri, 12 Jan 1996 11:49
55 lines
3049 bytes
Karl-Heinz Krause (Krause@t-online.de) wrote:
[ DEL: ... ]
: Das ist keine Lvsung des Problems. Sicher, hier in diesem Beispiel
: funktioniert es. Es ging mir aber vor allem um folgenden Fall: Gegeben
: sei eine Systemfunktion SyFu, die als Parameter einen Funktionszeiger
: erwartet.
: 	void SyFu (int(*fptr)());

Ach so, darum ging es.. (*Groschen fall*)

: Die |bergebene Funktion wird dann vom Betriebssystem bei Eintreten
: bestimmter Ereignisse aufgerufen. Sowas kommt bei GUI-Programmierung
: hdufig vor, ebenso bei Netzwerkprogrammierung; |berhaupt immer dann,
: wenn auf asynchrone Ereignisse reagiert werden soll.

Yep. Gerade im Zusammenhang mit Netzwerkprogrammierung hatte ich mal
das gleiche Problem.

: Ich will jetzt an SyFu eine Funktion |bergeben, die die Methode "method"
: f|r das bestimmte X-Objekt "a" aufruft. Wenn gebundene Methoden
: existieren w|rden, wdre das einfach:
: 	SyFu (a.method);
[ DEL: ... ]

: In der Praxis benutzt man dazu folgenden Trick: Man setzt an den Anfang
: eines Xmethod-Objekts einige zusdtzliche Bytes, die im wesentlichen die
: Maschinencodes f|r einen Funktionsaufruf enthalten. Dadurch wird
: erreicht, da_ die Adresse eines Xmethod-Objekts auch als Adresse einer
: Funktion betrachtet werden kann, die beim Aufruf gerade das Gew|nschte
: macht, ndmlich
: 	(fptr.object)->*(fptr.method)

: Karl-Heinz Krause

Tja, genau diesen Trick habe ich in eine Funktion eingebaut, die mir
aus einem Zeiger auf die Objekt-Instanz, einem Zeiger auf die Member-
Funktion und einer Parameterbeschreibung dynamisch Maschinencode erzeugt,
der den Aufruf der Methode korrekt abwickelt.
Diesen Code speicher ich in einer Variablen des Objektes ab (bzw. den 
Zeiger darauf), so dass jede Instanz ihren eigenen Proxy-Code besitzt.

Die Parameterbeschreibung dient dazu, Parameter aus Prozessorregistern
C++-konform auf dem Stapel zu legen (, und evtl. wieder zurueckzugeben).
Dies ist sehr praktisch, da Systemfunktionen ihre Parameter gerne in
Registern uebergeben.

Portabel ist das ganze natuerlich nicht mehr. (Meine Version ist fuer
PC's ab 386, BC++/TC++, ??DOS.)

Reinhard.
--
 /-- Reinhard Pfau --- (ED-Pfau) --------------------------------------------\
| eMail: gz342@appl2.hrz.uni-siegen.de  |  IRC: Mubo  | no home-page         |
+----------------------------------------------------------------------------+
|  "Keyboard error - press F1 to continue"   (PC-BIOS)                       |
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads