Funktionszeiger
-
Hey,
ne die Methode Search sucht nach JPGs im übergebenen Ordner und soll ein Callback aufrufen, wenn eine JPG gefunden wurde. Wenn jetzt eine Klasse mehrere Methoden mit Suchanfragen hat, dann brauch sie auch mehrere Methoden die die gefundenen Datein auswertet. Und dann weis die Search-Methode nicht welche Interface-Methode sie aufrufen soll...
MfG Bergmann.
-
Bergmann89 schrieb:
ne die Methode Search sucht nach JPGs im übergebenen Ordner und soll ein Callback aufrufen, wenn eine JPG gefunden wurde. Wenn jetzt eine Klasse mehrere Methoden mit Suchanfragen hat, dann brauch sie auch mehrere Methoden die die gefundenen Datein auswertet.
Nö. sie braucht nur eine Callbackmethode, die im Zweifel anhand einer Klassenvariable rausfinden kann, welche "version" des callbacks denn grade gemeint ist.
/edit: allerdings kommt mir das Design etwas spanisch vor. Kannst du mal einen etwas weiteren Überblick geben, wer da was macht bei deinen Klassen/objekten?
-
Mach ein Template aus der Funktion, und gib nen beliebigen Funktor mit.
Oder verwende std::function.
-
Hey,
ich hab ne Klasse Utils, die stellt verschiedene Methoden zur Verfügung die vom Programm in allen Bereichen heufig benutzt wird. Darunter auch die searchJPGFiles-Methode.
Dann hab ich eine Klasse die sich um die Dateneingabe kümmert, mit einem Menü. In dem Menü kann der User allerhand Sachen einstellen nach denen gesucht werden soll, bzw. welche JPGs bearbeitet werden sollen. Dort kann er z.B ein CameraModel festlegen mit der die JPGs aufgenommen wurden. Wenn er das Model aber nicht 100%tig weis, dann wird eine Suche in dem Ordner gestartet und alle CameraModele aus den exif-Daten der JPGs ausgelesen und dem User angezeigt. Die Suche übernimmt natürlich die searchJPGFiles-Methode und die Auswertung der Daten soll dann die Callback-Methode machen.
Weiterhin gibt es eine Klasse, die die gewünschten Operationen dann ausführt. Die startet auch eine Suche über die searchJPGFiles-Methode und führt in ihrer Callback-Funktion die gewünschten Aktionen aus (Datein umbennen, kopieren, verschieben, ...).
So ist die Suche universell einsetzbar und kann über die Callbacks von fast jeders Methode genutzt werden. Nur leider gingen die Callbacks nich so wie ich wollte (oder ich habs noch nich verstanden) und deshalb bin ich notgedrungen auf ein Interface umgestiegen...MfG Bergmann.
-
Ich hätte das etwas weiter aufgebröselt:
- searchJPGs macht genau was der Name sagt - es sucht nur die jpgs und gibt einen Container voller Dateihandles/Referenzen (in welcher Form auch immer, vielleicht auch nur filenamen) zurück.
- Über das Ergebnis wird iteriert, und zwar mit einem Funktor, der solch ein Filehandle nimmt und damit *irgendwas* macht. Das *irgendwas* kann eben öffnen + kamerainfo lesen sein, oder öffnen + bearbeiten etc.
Wenn du Dateien immer öffnest und was tust, kannst du das erreichen, indem du den Funktor in schritt 2 aus einem Fileopener + Fileprocessor zusammensetzt - wobei der Fileprocessor wieder generisch irgendein Funktor sein kann, der auf eine geöffnete jpg-Datei losgelassen wird. Templates lassen grüßen

Auf jeden Fall würde ich die Kopplung durch das Interface und Ableitungen etc. möglichst vermeiden.
-
Hey,
das mit den Functoren hab ich gecheckt (denke ich). Diese Seite hat mir sehr dabei geholfen: http://www.newty.de/fpt/functor.html
Jetz würd ich aber gern noch wissen wie das mit dem std:function geht. Meine IDE (CodeLite) zeigt mit das bei der Codevervollständigung an, aber der Compiler (GNU G++) sagt folgendes:error: ‘function’ in namespace ‘std’ does not name a type
MfG Bergmann.
-
Dann kennt dein Compiler std::function noch nicht (ist Teil des TR1 bzw. auch des neuen C++ Standards).
Verwende derweilen einfach std::tr1::function oder boost::function.
-
function gibts erst ab C++0x in der standardbibliothek. wird z.B. von MSVC2010 und gcc 4.6 (?) unterstützt. Alternativ kannst du vorher boost.function benutzen. (google hilft da weiter)

-
Hey,
ich hab g++ 4:4.5.2-1ubuntu3. std::tr1::function gibts auch nicht. Sin die auch erst ab v4.6 dabei? Die Boost-Librarie wollt ich umgehen, da ich das ganze noch meinem Prof schicken muss und da sind haufen extra Libs nich so gut.
Ich werd jetzt auch die Functoren mit nem Template nutzen. Ich wollt halt nur rein Intresse halber wissen, warum er das mit den functions bei mir net findet...MfG Bergmann.
-
Bergmann89 schrieb:
ich hab g++ 4:4.5.2-1ubuntu3. std::tr1::function gibts auch nicht. Sin die auch erst ab v4.6 dabei? Die Boost-Librarie wollt ich umgehen, da ich das ganze noch meinem Prof schicken muss und da sind haufen extra Libs nich so gut.
die boost libraries sind fast standard. Frag am Besten deinen Prof, ob er sie hat.
-
Hey,
das mit den Functoren un den Templates läuft jetzt. Jetzt hab ich nur noch eine kleine Frage. Und zwar hab ich den Code des Templates vollständig im Header unter gebracht. Dort arbeitet er auch. Aber sobald ich den eigentlichen Code in der .cpp unterbringen will schmeißt er mir cryptische Fehler aus.
So sieht der Code aus (.h):class IFileHandlerFunctor{ public: virtual void operator()(const char* path) = 0; virtual void call(const char* path) = 0; }; template <class TClass> class TFileHandlerCallbackFunctor: public IFileHandlerFunctor{ private: void (TClass::*_callback)(const char*); TClass *_obj; public: virtual void operator()(const char* path){ (*_obj.*_callback)(path); }; virtual void call(const char* path){ (*_obj.*_callback)(path); }; TFileHandlerCallbackFunctor(TClass *obj, void(TClass::*callback)(const char*)){ _obj = obj; _callback = callback; }; };das hab ich probiert (*.cpp, natürlich die *.h vorher angepasst):
template<class TClass> void TFileHandlerCallbackFunctor<TClass>:: operator()(const char* path){ (*_obj.*_callback)(path); } template<class TClass> void TFileHandlerCallbackFunctor<TClass>::call(const char* path){ (*_obj.*_callback)(path); } /**Konstruktor * @obj: Objekt das die Callback Methode besitzt * @callback: Funktionszeiger auf Callback-Methode des Objekts template<class TClass> TFileHandlerCallbackFunctor<TClass>::TFileHandlerCallbackFunctor(TClass* obj, void(TClass::*callback)(const char*)){ _obj = obj; _callback = callback; }Fehler: Die Template-Klasse an sich lässt sich ohne Probleme compilieren, doch wenn ich das Ganze dann auch benutzen will kommt dieser Fehler:
undefined reference to `TFileHandlerCallbackFunctor<TexifDataInput>::TFileHandlerCallbackFunctor(TexifDataInput*, void (TexifDataInput::*)(char const*))'So sieht der Aufruf zu dem Fehler aus:
TFileHandlerCallbackFunctor<TexifDataInput> callback(this, &TexifDataInput::searchJPGFileHandler); TUtils::searchJPGFiles(((Mode2Data*)_inputData->modeData)->source.c_str(), _inputData->searchSubDir, &callback);Das seltsame is, das dieser Code funktioniert, wenn ich den Code ausschließlich in die *.h schribe. Sobald ich ihn in die *.cpp packe (wo er ja normalerweise stehen sollte) meckert er rum -.-
Kann sich das jmd erklären?MfG Bergmann.
-
Bergmann89 schrieb:
Das seltsame is, das dieser Code funktioniert, wenn ich den Code ausschließlich in die *.h schribe. Sobald ich ihn in die *.cpp packe (wo er ja normalerweise stehen sollte) meckert er rum -.-
Kann sich das jmd erklären?Diese Regel gilt für normale Funktionen, allerdings nicht für Templates. Bei einem Template muß der Compiler die komplette Definition sehen wenn er es instanziiert (im Hauptprogramm) - und das geht nur, wenn die Definition direkt im Header steht.
(eine Alternative wäre noch eine .impl Datei, die du am Ende des Headers einbindest)
-
Hey,
wenn das so üblich is, dann lass ich das im Header. Ich wollt dann bloß kein Punktabzug bekommen, weil ich mich nich an die Styleregeln gehalten hab.
Damit wären dann alle Fargen beseitigt. Danke an alle für die Mühe
MfG & Thx Bergmann