Functor, Functionszeiger
-
Guten Tag,
habe mir schon sehr viele Programmtexte angesehen mit Funktionsobjekten (Funktoren).
Jetzt war meine Idee, daß ich eine Klasse für einen functor anlege und dieses Object in einer anderen Klasse verwende...
#include <iostream> class Functor { protected: // function to call a memberfunction to display the data contend of a variable std::string (*functionptr)(); public: Functor(); std::string operator()(std::string (*functionptr)()); }; Functor::Functor():functionptr(0) {} std::string Functor::operator()(std::string (*fptr)()) { functionptr=fptr; } class address { protected: std::string firstName; std::string secondName; std::string (address::*pfn)(); // this is a functionpointer with the name pfn public: Functor f_pfn; address(std::string _firstName="mein", std::string _secondName="Name"); std::string getfirstName(); std::string getsecondName(); void ausgabeinit(); void execute(); }; address::address(std::string vname, std::string nname):firstName(vname), secondName(nname), pfn(0) { std::cout << "\nconstructor pfn: " << pfn << std::endl; } std::string address::getfirstName() { return firstName; } std::string address::getsecondName() { return secondName; } void address::ausgabeinit() { pfn=&address::getfirstName; std::cout << "\nausgabeinit() pfn: " << pfn << std::endl; std::cout << (this->*pfn)() << std::endl; } void address::execute() { std::cout << "\naddress::execute(): " << (this->*pfn)(); } int main() { Functor malso; address icke; std::cout << "Vorname: " << icke.getfirstName() << std::endl; icke.ausgabeinit(); icke.execute(); std::cout << "\nicke(getsecondName()): " << icke.(address::getsecondName()) << std::endl; return 0; }als fehlermeldung kommt:
g++ -o mitfunktor functorclass.cc functorclass.cc: In Funktion »int main()«: functorclass.cc:72:52: Fehler: expected unqualified-id before »(« token functorclass.cc:72:76: Fehler: Elementfunktion »std::string address::getsecondName()« kann nicht ohne Objekt aufgerufen werdenwas muß ich tun damit ich den operator() des functors aufrufen kann? Oder besser wo mache ich den Fehler?
der functor ist ein public-element und müsste aufrufbar sein, ein object habe ich doch auch gebastelt...

-
Kennst du std::function?
-
Nach icke muss der Punkt weg. Und nach address::getSecondName die Klammern. Außerdem geht das nicht, da address::getsecondName eine Memberfunktion ist, die Funktion operator() nimmt aber einen Funktionpointer, keinen Memberfunktionpointer.
-
Versteh ich richtig, obwohl Functor ein Attribut von address ist, darf ich nicht auf die memberfunktionen von address zugreifen?nein, std::function habe ich zwar schonmal im Netz gelesen, aber kennen tu ich's nicht.
Bin absoluter Anfänger und versuche die "logischen" Grundlagen zu verstehen, damit ich weiß was ich mache wenn ich ein Programm schreibe...
erst mal vielen dank, dann versuch ich's mal mit deinem Tip
-
Außerdem, wo benutzt du den Funktor überhaupt

-
In dem Code versuche ich im "main" den Functor zu benutzen... dachte ich da ja die class address keinen operator() hat... wäre es ein Lösung in address einen operator() einzubauen der die verschiedenen Ausbage- get-funktionen aufruft

-
Erst mal den Code
bool Person::SetFunctionsPtr() { bool (Person::*SetFunctions[PERSON_ATTRIBUTES])(std::string) = {&Person::SetPersonID, &Person::SetAddress, &Person::SetFirstName, &Person::SetSecondName, &Person::SetNameAffix, &Person::SetTitle}; std::string (Person::*GetFunctions[PERSON_ATTRIBUTES])() const={&Person::GetPersonID, &Person::GetSecondName, &Person::GetFirstName, &Person::GetNameAffix, &Person::GetAddress, &Person::GetTitle}; if(SetFunctions && GetFunctions) { std::cout << "SetFunctions: " << SetFunctions << std::endl; std::cout << "GetFunctions: " << GetFunctions << std::endl; return true; } else return false; } bool Person::SetPerson() { std::cout << "In SetPerson SetFunctions: " << Person::SetFunctions << std::endl; std::cout << "In SetPerson GetFunctions: " << GetFunctions << std::endl; } #include "person.h" int main() { Person probemensch; probemensch.SetPerson(); return 0; }Kurze Erläuterung meiner Idee: Die Zeiger sind Members der Klasse person, also, so dachte ich, von allen Methoden aufrufbar. Da ich diese member öfter benutzen will habe ich sie in der klasse implementiert. Im Konstruktor bekomme ich auch addressen von den Zeigern angezeigt, aber dann in der methode SetPerson() folgendes:
enklasse/src$ ../verwaltung SetFunctions: 0xbf8ab990 GetFunctions: 0xbf8ab9c0 Weiter geht's mit irgendeiner Taste... In SetPerson SetFunctions: 0xbf8abcbc In SetPerson GetFunctions: 0xbf8abcbcAlso denke ich, daß ich irgendwo einen Fehler in der syntax/logik habe da auch mit &SetFunctions oder *SetFunctions nicht die adresse angezeigt wird in SetPerson wie in dem Konstruktor...
Leider finde ich keine Möglichkeit, bzw. habe keine Idee wie ich den zeiger aufrufen muß damit die gewünschte "Adresse" bzw. die Funktion hinter der Adresse ausgeführt wird...
-
Was soll das denn alles? Worum geht's dir? Was hat da ein Elementfunktionszeiger in der Klasse address zu suchen? Warum hast du ein
#include "person.h"hinter den Definitionen von Sachen aus der Person-Klasse? Ich glaube, du machst alles viel komplizierter als nötig ...#include <iostream> #include <string> struct address { std::string firstname; std::string secondname; }; typedef std::string address::*amemptr; int main() { using namespace std; address a = { "Hans", "Wurst" }; amemptr m = &address::firstname; cout << (a.*m) << endl; m = &address::secondname; cout << (a.*m) << endl; }
-
Nun, ich will einen Funktionzeiger in meiner Klasse haben um dann über eine Zahl die notwendige Funktion zur Ausgabe bzw. Veränderung des Wertes der in der Variabelen steht zu verändern...
Weil ich "träge" bin dachte ich es wäre am einfachsten wenn ich einen Zeiger auf die Funktionen deklariere und definiere, damit ich sie aufrufen kann, aber ich kriegs nicht hin

-
thepower schrieb:
um dann über eine Zahl die notwendige Funktion zur Ausgabe bzw. Veränderung des Wertes der in der Variabelen steht zu verändern...
Warum? Das erschließt sich mir nicht.
-
...könnte sein, daß ich falsch liege, aber ich habe im Moment folgendes im Header stehen:
// Header for class person // 30.05.2012 #ifndef _PERSON_H #define _PERSON_H #ifndef STRING_H #include <string> #endif #ifndef _GLIBCXX_FSTREAM #include <fstream> #endif class Person { protected: // static members static unsigned int NumberOfPersons; static const int PERSON_ATTRIBUTES; // static methods // functions to Set/Get the allowed values of IDs static unsigned int SetNumberOfPersons(); static unsigned int GetNumberOfPersons(); // Tools to make functions usable unsigned int CountMembersFile(); // Datamembers of person: PersonID:second name:first name:name affix (jun. or something else):Addressing:title (Dr. or so on) unsigned int PersonID; std::string SecondName; std::string FirstName; std::string NameAffix; std::string Address; std::string Title; // Filename in which the data is stored std::string FileNamePerson; // Filepointers std::fstream InFilePersons; // Put data in File FileNamePerson std::fstream OutFilePersons; // Get data from File FileNamePerson // Pointer to the Set-functions Set to 0 in constructor bool(Person::*SetFunctions[])(std::string); // Pointer to the Get-functions Set to 0 in constructor std::string (Person::*GetFunctions[])() const; public: // Constructor with default values Person( unsigned int _PersonID=0, std::string _SecondName="Scheidt", std::string _FirstName="Marianne", std::string _NameAffix="jun.", std::string _Address="Herr", std::string _Title="", std::string _FileNamePerson="customerNames.dat"); // Destructor "virtual" if it is needed in derived classes virtual ~Person() {} // Set values of the functionpointers virtual bool SetFunctionsptr(); #if 0 // Set values of a whole person virtual bool SetPerson(); // Set values of a person virtual bool SetPersonID(std::string _personID); virtual bool SetSecondName(std::string _in); virtual bool SetFirstName(std::string _in); virtual bool SetNameAffix(std::string _in); virtual bool SetAddress(std::string _in); virtual bool SetTitle(std::string _in); // function to change the Set values of a variable bool ChangeValues(int selection); // selection is the number of the choosen variable //Get-functions to "use" the variable values of Person virtual std::string GetPersonID() const; virtual std::string GetSecondName() const; virtual std::string GetFirstName() const; virtual std::string GetNameAffix() const; virtual std::string GetAddress() const; virtual std::string GetTitle() const; // Function to Set the Menue which the users need to run the application virtual void Menue(); // Function to write the Person to in form: // Person Nummer: PersonID // Anrede: Address Title: Dr. med. // Vorname: FirstName // Nachname: SecondName // Anhang: NameAffix virtual void Output() const; // Function to read the file with the stored Persones // std::string filename is the name of the file in which the // Persones are stored bool ReadFile(std::string filename); #endif }; #endifimmper wenn ich eine set- oder getfunction benögte rufe ich sie mit ihrem namen auf, wenn ich alle brauche rufe ich 6 mal die namen von set- oder get- auf... wenn ich das ganze in ein pointerarray lege kann ich mit for(int i = 0; i < sizeof(pointerarray); ++9) die aufrufe vereinfachen... dachte ich