Funktionsübergabe

26/02/2011 - 11:15 von Matthias | Report spam
Hallo zusammen,

ich habe mal eine Frage. Ich habe eine Funktion in der einige Dinge
getan werden, u.a. wird eine weiter Funktion eines Memberobjektes
aufgerufen. Da in dieser ersten Funktion immer das gleich getan wird,
würde ich gern eine allgemeingültige Funktion draus machen, der man
die zweit Funktion übergibt. Also ich etwa so:

BOOL CClassA::Check(CEditEx* ctrlField, void (*setMethod)(string&))
{
CString value;
ctrlField->GetWindowText(value);

try
{
string strValue = value.GetString();
setMethod(strValue);
return TRUE;
}
catch (CMyException e)
{
ctrlField->SetBackgroundColor(RGB(255,0,0));
return FALSE;
}
}

Die set Methode ist in einem Memberobjekt enthalten, d.h. ich müsste
den Aufruf gestalten:

Check(&field, m_memberObject->SetMethod);

So gehts aber nicht. Ist das überhaupt möglich oder was mache ich
falsch?
 

Lesen sie die antworten

#1 Edzard Egberts
26/02/2011 - 15:36 | Warnen spam
Matthias schrieb:

ich habe mal eine Frage. Ich habe eine Funktion in der einige Dinge
getan werden, u.a. wird eine weiter Funktion eines Memberobjektes
aufgerufen. Da in dieser ersten Funktion immer das gleich getan wird,
würde ich gern eine allgemeingültige Funktion draus machen, der man
die zweit Funktion übergibt.

Die set Methode ist in einem Memberobjekt enthalten, d.h. ich müsste
den Aufruf gestalten:

Check(&field, m_memberObject->SetMethod);

So gehts aber nicht. Ist das überhaupt möglich oder was mache ich
falsch?



Das ist möglich, man kann nàmlich einen Funktionspointer mit this-Zeiger
definieren und übergeben, das sollte per Suchmaschine eigentlich recht
einfach zu finden sein. Ich weiß also, dass es das gibt, kann Dir aber
ohne selber nachzuschlagen nicht sagen, wie es funktioniert, weil ich
das schon seit Jahren nicht mehr gemacht habe.

Meiner Meinung nach gibt es nàmlich eine bessere, objektorientierte
Methode, das abstrakt virtuelle Interface. Funktionszeiger sollte man
IMHO für statische Methoden oder eben Funktionen benutzen, ansonsten ein
Interface:

"interfacefoo.h"

#ifndef INTERFACEFOO_H
#define INTERFACEFOO_H

#include <string>
using std::string;
#include "field.h"

struct interface
{ // das kann auch eine class sein
virtual void SetMethod(string S)= 0;
}

/* Das ist eine reine Deklaration, die definiert, wie eine (oder
mehrere) Methoden aufgerufen werden. "virtual ... = 0" sagt, dass das
übersschrieben werden muss und ist der eigentliche Trick. Die packst Du
in den gleichen Header, in dem auch Deine universelle Funktion steht,
die dann etwa so aussieht: */

void Check(field& F, interface& I)
{
string S= "Not Cecked"; // Wenn mal nichts zu tun ist ;o)
I.SetMethod(S);
}
#endif

Nun kannst Du beliebige Objekte für diese Funktion "freigeben", indem Du
das Interface als Basisklasse angibst:

#include "interfacefoo.h"

class myclass: public interface
{
public:
myclass()
{ // Aufruf der Funktion mit Übergabe
// des Interface:
Check(myField, *this);
}

virtual void SetMethod(string S)
{ // Diese Methode wird von Foo aufgerufen
myMember= S;
}
};

Auf den ersten Blick sieht das ziemlich umstàndlich aus, wenn man sich
aber mal dran gewöhnt hat, ist das eine sehr elegante und vielseitige
Lösung, die vor allem auch recht fehlertolerant ist - man hantiert mit
gut definierten Objekten und kann Referenzen verwenden, statt Zeiger,
die immer mal irgendwie ins Nirwana deuten können. Das ist auch schön
geeignet, um verschiedene Objekte miteinander zu verbinden, die dann
nicht mehr voneinander wissen müssen, als die Interfacedeklaration.

Ähnliche fragen