C++ in std::map Pointer auf Funktionsobjekte speichern

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
schorsch_76
Beiträge: 2607
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von schorsch_76 » 02.09.2011 19:56:39

Hi alexander_ro,
ich hab da gleich mal ein paar Anerkungen für dich :)

a) Event.cpp/.hpp:

Code: Alles auswählen

//******************************************************************************
//* Implementierung: Event                                                     *
//******************************************************************************
template<class eventResult, class eventParam>
eventResult Event<eventResult, eventParam>::operator() (eventParam)
{
  syslog (LOG_INFO, "Event<eventResult, eventParam>::operator () ()");
}
Das hier ist in der *.cpp OBWOHL die Klasse Event<> ein template ist. Das wird der Compiler so nicht mögen. Templates werden immer in den Header Dateien vollständig implementiert. Das Schlüsselwort "export" hat nur beim Comeau Compiler funktioniert und ist ab C++11 deprecated [1] .

export wäre von nöten, wenn du Template Vorlagen welche Projektweit via Header eingebunden werden.

Praktisch alle template Header machen erst die Klassendefinition und anschliessend die Implementierung .. im Header.

Wenn du das Template nur in dieser Übersetzungseinheit benötigst, kann man das aber so machen.

[1] http://en.wikipedia.org/wiki/C%2B%2B0x# ... deprecated

b) Event.cpp Zeile 87: Das typename ist überflüssig ;)

c) Wenn du das typedef in abhängigkeit vom Event machen willst, muss der Event ein Typ sein. Das würde aber wieder bedeuten, dass Xml ein Template werden muss. Das würde bedeuten, dass jeder Event seine eigene XML Implementierung hat. (vermutlich nicht so von dir gewünscht)

ODER:

Du leitest alle Events von einer Basisklasse ab, welche dein Interface implementieren. Wie weiter vorn im Thread beschrieben. Vor einem oder zwei Jahren hatte ich ein ähnliches Problem welches ich auch unbedingt mit templates lösen zu müssen meinte, dabei war Vererbung mit abstrakter Basisklasse die Lösung.

Du hast sowie ich das sehe folgende Anforderungen an das Design:
- Du willst zu einer string id einen speziellen Event auslösen.
- string id und Event sollen über eine map verknüpft werden.
- alle Events haben das gleiche Interface, aber unterschiedliche Implementierungen.
- alle Events sollen in einen Container eingehängt werden.

Unterschiedliche Typen in einen Container packen, geht in C++ nur über Basisklassen (oder unter Umständen über boost::tuple. hab damit noch nichts gemacht). Tuples deuten aber sehr oft auf eine "Notlösung" hin.

Um wieder auf die spezifischen Typen zugreifen zu können wird dann ein Visitor (double dispatch) eingesetzt.

Gruß
schorsch

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 02.09.2011 20:51:20

Hi Schorsch,

Ideen sind immer gefragt. Wie Du unten noch lesen wirst bin ich oder der Compiler nicht immer Deiner Meinung. Über das mit der Abstrakten Klasse muss ich erst nochmal Nachdenken.

a) Wozu »export« ? Ich benutze den gcc aus dem Debian Paket der mag das so. Ich habe »export« schon lange nicht mehr gebraucht und wenn es jetzt als veraltet gilt warum sollte ich es benützen. Eigentlich habe ich es bisher nur für DLLs gebraucht.

b) Ohne das Überflüssige sagt der Compiler folgendes:

Code: Alles auswählen

gcc -c -g --std=c++0x HtsWebGen.cpp
In file included from ExecXmlBauplan/ExecXmlBauplan.cpp:35,
                 from HtsWebGen.cpp:48:
ExecXmlBauplan/../../../HtsApi_1.0/Event/Event.cpp: In member function ‘void hts::EventList<eventId, eventTyp>::sendEvent(eventId)’:
ExecXmlBauplan/../../../HtsApi_1.0/Event/Event.cpp:87: error: expected `;' before ‘pos’
ExecXmlBauplan/../../../HtsApi_1.0/Event/Event.cpp:89: error: ‘pos’ was not declared in this scope
ExecXmlBauplan/../../../HtsApi_1.0/Event/Event.cpp: In member function ‘void hts::EventList<eventId, eventTyp>::sendEvent(eventId) [with eventId = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, eventTyp = hts::Event<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]’:
../../HtsApi_1.0/Xml/Xml.cpp:419:   instantiated from here
ExecXmlBauplan/../../../HtsApi_1.0/Event/Event.cpp:87: error: dependent-name ‘std::map::iterator’ is parsed as a non-type, but instantiation yields a type
ExecXmlBauplan/../../../HtsApi_1.0/Event/Event.cpp:87: note: say ‘typename std::map::iterator’ if a type is meant
make: *** [HtsWebGen.o] Fehler 1
sieht nicht so aus als würde er (der Compiler) es so sehen wie Du :wink:
Das ist eigentlich immer so wenn ich Template Parameter in einem Template für eine Templatespezialisierung benutze. Was für ein Satz ... :roll:

c) Ja richtig ist nicht so gedacht.

ODER

Hm, muss ich nochmal darüber nachdenken.

Nun ja, Basisklasse hab ich ja. Die ist halt ein Template weil ich Events mit verschiedenen Datentypen als Parameter benutzen will. Klar wenn sich die unterscheiden kann ich die nicht mehr in einer EventList haben aber das brauchts auch nicht. Es hindert mich ja keiner mehrere dieser EventList für verschiedene Aufgaben zu benützen.
Es ist halt in diesem Fall eine String-ID. Um numerische Aufgaben zu lösen könnte ich mir aber auch vorstellen einen int od. double da zu benutzen (evtl. zum analysieren von Binärdateien).

Ich kenne in der zwischen Zeit einiges von boost, mag boost nicht besonders. Die haben sich da sicher viel Arbeit gemacht aber manche Dinge sind einfach viel zu Umständlich als das sie einen Mehrwert bedeuten. Gut wenn es nicht anders ging und es nach meiner Meinung eine schönere Lösung mit boost gäbe würde ich es auch benutzen. Ich sehe da aber keine ...
Du meintest ja auch Tuples wären nicht der rechte Weg.

Grüße
Alexander

EDIT: Hier findet man die vom Event-Template abgeleiteten Events: HtsWebGen/src/ExecXmlBauplan/ExecXmlBauplan.hpp

Benutzeravatar
schorsch_76
Beiträge: 2607
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von schorsch_76 » 02.09.2011 21:08:23

alexander_ro hat geschrieben:Hi Schorsch,
a) Wozu »export« ? Ich benutze den gcc aus dem Debian Paket der mag das so. Ich habe »export« schon lange nicht mehr gebraucht und wenn es jetzt als veraltet gilt warum sollte ich es benützen. Eigentlich habe ich es bisher nur für DLLs gebraucht.
Du meinst das __declspec(dllexport) . Da ist was ganz anderes ;)
siehe [1] zu Comeau export

Ja du hast deine Basisklasse, welche ein Template ist. Diese kannst du leider ohne einen Templateparameter (welcher eintweder direkt von dir kommt oder einem template parameter der XML Klasse) nicht in die map packen ;)

Gruß
schorsch

[1] http://www.comeaucomputing.com/4.0/docs ... xport.html

EDIT:
Das typename ist an sich überflüssig. Du sagst dem Compiler halt nur zusätzlich, das dies hier ein Typ sein soll. Gibst ihm sozusagen "Hilfestellung" ;) Wenn er das braucht, dann ist das halt so :)

Zu Boost: Ich arbeite jetzt 12 Jahre in der Softwareentwicklung permanent mit C/C++. Lerne (fast) jeden Tag was neues dazu und boost hat mir das Leben seeehr erleichtert. Ohne boost, wäre ich fast hilflos ;)

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 02.09.2011 22:18:55

Ah, andere export Baustelle den kannte ich noch nicht. Im Moment mal lass ich das so. Mein Compiler stört sich daran nicht und wenn wäre das ja schnell in eine Datei kopiert.

Der Templateparameter kommt jetzt von der Klasse die diese Art Event benutzt. In diesem Fall Xml das ist auch gut so weil von der ja auch die zu verarbeitenden Daten kommen. Xml muss aber nicht wissen wie im Detail die verarbeitet werden sondern sagt einfach mach mal. Es ist dann die Aufrufende Klasse die passende Events als Templatespezialisierung zur Verfügung stellt. Ich meine die typedefs sind zwar nicht schön aber schöner gehts halt nicht.

So könnte es vielleicht gehen:

Code: Alles auswählen

template <...> class Event
{
  class EventList {};
}
Oder? EDIT: nee ist Quatsch geht auch nicht.

Grüße
Alexander

EDIT: Ja Software entwickel ich auch schon lange viel C++ aber nicht nur.

EDIT2: boost hat für generische Programmierung ein bisschen hilfreiches da gäbe es aber auch Loki noch. Aber das Netzwerk Zeug ist Mist total vermurkste Schnittstelle.

Benutzeravatar
schorsch_76
Beiträge: 2607
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von schorsch_76 » 02.09.2011 22:31:27

Boost::asio ist halt auf asynchrone Kommunikation ausgelegt. Asynchrone Sachen sind nie sehr leicht, wenn das ganze die Hardware bis an die Grenzen bringen können soll. Hier hilft auch wieder .. üben .. versuche .. üben .. Erfolg :)

Loki kommt ja von Alexandrescu, der afaik auch an boost mitarbeitet. Ebenso wie Herb Sutter. Zwei Giganten in der C++ Programmiersprache :)

Am Ende läuft dein Problem darauf hinaus, was mit deinem Design möglich ist und wo es an die Grenzen stöst. Du musst dir nur klar machen was dir wichtig ist und was das Ding können soll und was ein absolutes MUST HAVE ist. Nur weil eine Lösung templates verwendet ist sie einer Vererbungslösung nicht überlegen.

Gruß
schorsch

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 02.09.2011 23:01:34

Nur weil eine Lösung templates verwendet ist sie einer Vererbungslösung nicht überlegen.
Warum benutzt man dann Templates?

Wenn man

Code: Alles auswählen

class Event
{
  virtual std::string operator() (std::string) = 0;
}

class xmlInsert : public Event
{
  std::string operator() (std::string)
  {
    ... guckst Du was zu tun ist ...
  }
}
als Basisklasse hat. Können ja die abgeleiteten nur wieder string als Parameter und Rückgabewert haben. Gut man könnte für jeden Typ dann eine neue Basisklasse machen. Anders ja, aber schöner?

Grüße
Alexander

Benutzeravatar
schorsch_76
Beiträge: 2607
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von schorsch_76 » 03.09.2011 00:41:58

Anders ja, aber schöner?
Ja, es erfüllt die Anforderungen ;)

Beispiel:

Code: Alles auswählen


// Visitor Basisklasse
class xmlInsert;
class backeBackeKuchen;

class VisitorBase
{
  virtual void Visit(xmlInsert* p_item) = 0;
  virtual void Visit(backeBackeKuchen* p_item) = 0;
};

// Event Basisklasse

class Event
{
  virtual void Accept(VisitorBase* p_visitor) = 0;

  //Hier muss operator() nicht virtuell sein, da der Visitor "weis" welchen Event er besucht
  //virtual std::string operator() (std::string) = 0;
}

// Event xmlInsert

class xmlInsert : public Event
{
  virtual void Accept(VisitorBase* p_visitor)
  {
     p_visitor->Visit(this);
  }
  void operator() (std::string)
  {
    ... guckst Du was zu tun ist ...
  }
}

// Event backeBackeKuchen

class backeBackeKuchen : public Event
{
  virtual void Accept(VisitorBase* p_visitor)
  {
     p_visitor->Visit(this);
  }
  void operator() (std::string)
  {
    ... guckst Du was zu tun ist ...
  }
}

// Visitor ruft operator() auf
class actionVisitor : public VisitorBase
{
  virtual void Visit(xmlInsert* p_item)
  {
     // hier kann dann xmlInsert daten bearbeiten
     (*p_item)(string der dem Visitor vorher als argument für das Event gegeben wurde)
  }
  virtual void Visit(backeBackeKuchen* p_item)
  {
     // hier kann dann backeBackeKuchen daten bearbeiten
     (*p_item)(string der dem Visitor vorher als argument für das Event gegeben wurde)
  }
};


// Visitor kann Ergebnisse etc pp auswerten
class resultVisitor : public VisitorBase
{
  virtual void Visit(xmlInsert* p_item)
  {
     // hier kann dann auf xmlInsert ergebnisse etc pp zugegriffen werden. [1]
  }
  virtual void Visit(backeBackeKuchen* p_item)
  {
     // hier kann dann auf backeBackeKuchen ergebnisse etc pp zugegriffen werden.
  }
};

Aufruf:

typedef std::map<std::string, std::shared_ptr<Event>> Id2EventCont;

// Id2EventMap Erzeugen
Id2EventCont Id2Evt;
Id2Evt["xml"] = std::shared_ptr<Event>(new xmlInsert);
Id2Evt["backen"] = std::shared_ptr<Event>(new backeBackeKuchen);

// geparste Daten
typedef std::list<std::string> StringList;
StringList	parse_results;
// Fülle ParseResult Contailer
Read(...)
Parse(...)

// gehe über die Liste und verarbeite Daten
actionVisitor worker;
for (StringList::iterator pos = parse_results.begin(); pos != parse_results.end(); ++pos)
{
	// stelle sicher dass dieser Event enthalten ist in mao
	Id2EventCont::iterator t = Id2Evt.find(*pos);
	if (t != Id2Evt.end())
	{
		std::shared_ptr<Event> p_evt = Id2Evt[*pos]; // pos zeigt auf den Tag, der diesen Event auslösen soll
		
		// hier könnte auch über ein allgemeines Interface aus der Event Basisklasse zugegriffen werden
		// wenn das nicht reicht, muss per double dispatch (visitor) gearbeitet werden und die arbeit im worker passieren
		worker.SetArgument(was weis ich was noch für argumente benötigt werden);
		p_evt->Accept(&worker);
	}
}

// Hier gehts jetzt über alle Daten die in der Liste enthalten sind
resultVisitor viewer;
for (EventCont::iterator pos = daten.begin(); pos != daten.end(); ++pos)
{
   (*(pos.second))->Accept(&viewer);
}
Die Eventobejekte xmlInsert und backeBackeKuchen können in der selben Liste enthalten sein und können im Visitor unterschiedlich behandelt werden. Können unterschiedliche Ergebnisse enthalten und für ihre Datenverarbeitung unterschiedliche Argumente bekommen und sogar unterschiedliche Funktionen innerhalb der Events aufrufen. Inversion of Control ;)

[1] Der Stack sieht hier dann so aus:
resultVisitor::Visit(xmlInserter*);
xmlInserter::Accept()
main.cpp:

Das iterieren über die Daten, das Handling der Parameter für die Events kann beliebig angepasst werden.

Gruß
schorsch

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 03.09.2011 10:04:57

Guten Morgen Schorsch,
Ja, es erfüllt die Anforderungen ;)
Er nu wieder ...
Gut Du kannst verschiedene Events in einer Liste Sammeln mag vielleicht manchmal ein Vorteil sein. Aber teuer erkauft. Für mich sieht es doch sehr viel komplizierter aus und hat einen großen Nachteil: wenn Du andere Events brauchst musst Du in den Tiefen Deiner Implementierung herumändern. Hier musst Du an sehr viel mehr stellen aufpassen als ich bei meinen zwei Typedefs. Da Du an einer meist recht Zentralen Komponente herumänderst wirst Du auch sehr viel mehr von Deiner Anwendung testen müssen. Der Aufwand für die Implementierung einer neuen Anforderung wird so deutlich zunehmen. Meiner Meinung nach ein sehr schwer wiegender Nachteil. Gerade bei mir weil mir für mein eigenes Projekt nur geringe Ressourcen zur Verfügung stehen.

Diese Muster sind hübsch und taugen auch mal als Anregung aber meist nicht eins zu eins für die Praxis. Weil vieles was einem diese Ami Bande da verkaufen will sehr teuer kommt.

Grüße
Alexander

Benutzeravatar
schorsch_76
Beiträge: 2607
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von schorsch_76 » 03.09.2011 13:10:36

Dieses Muster habe ich geschäftlich sehr häufig im Einsatz. Das funktioniert. Wie dem auch sei ... solltest du eine Template Lösung haben, wäre ich interessiert diese zu erfahren ;)

Diese Muster müssen auch nicht immer 1 zu 1 umgesetzt werden. Sie sind Hilfsmittel um wiederkehrende Probleme zu lösen.
Gruß
schorsch

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 03.09.2011 16:41:19

Ich habe nicht behauptet das sie nicht funktioniert das tut sie. Ich behaupte sie erhöht den weiter Entwicklungs- und Wartungsaufwand das tut sie auch. Mir ist bekannt das die IT-Abteilungen dieser Welt wenig Wert auf geringe Aufwände legen. Deshalb kosten ja kleinste Anforderungen gleich Millionen. Auch wenn dort natürlich jeder behauptet das sei nicht so.

Ich Entwickle seit vielen Jahren schon Software für Finanzdienstleister, TK und Industrie. Dort hechelt man jedem angeblichen Trend hinterher der angeblich die Milliarden Einsparungen bringt. Den ersten den ich mitbekam war Outsourcing (Neudeutsch: Cloud Computing) damals wie heute in Deutschland ein Megaflop. Den meisten hat er viel gekostet ohne Nutzen. Der zweite ist XML gewesen nach wie vor die Weltweit Sinnloseste Verschwendung von enormen Ressourcen. XML ist eine Super Idee wird aber leider Total Hirnlos eingesetzt. Es ist nichts gewonnen wenn man alle Daten in Textform darstellt nur weil Menschen zu blöd sind Binärdaten zu lesen. Das ist nur gnadenlos Ineffizient. Auch mit Offenheit hat das wenig zu tun den auch binär Schnittstellen kann man offenlegen. Würde man es Sinnvoll machen dann die Binärschnittstelle in XML beschreiben und daraus dann eine Effiziente Schnittstelle für die Datenübergabe generieren. Der übliche Spruch das XML Daten Menschen lesbar sind zeigt deutlich das keiner je Nachgedacht hat was er da tut. Wie viele Menschen werden den XML-Code Ihrer OpenOffice oder Word Dokumente selber lesen geschweige den ändern. Hier bezahlt die ganze Welt für teuer erkaufe Möglichkeiten die keiner braucht. Der aktuelle Pleite Trend sind die Muster. Das Symptom von mir als »Mustermania« getauft. Grassiert derzeit in den IT Abteilungen. Selber denken wurde durch Muster abkupfern ersetzt.

Meine Template Lösung kennst Du ja schon scheint Dir aber nicht recht zu gefallen. Macht aber nix ... muss es auch nicht ... ich habe ja das Projekt angefangen um meine eigenen Ideen umzusetzen. Bei Kundenprojekten muss ich leider auf Wunsch des selbigen auch der Mustermania verfallen.

Selber denken macht schlau, nicht blindes abkupfern.

Grüße
Alexander

Benutzeravatar
schorsch_76
Beiträge: 2607
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von schorsch_76 » 03.09.2011 19:53:06

alexander_ro hat geschrieben:...
Meine Template Lösung kennst Du ja schon scheint Dir aber nicht recht zu gefallen. Macht aber nix ... muss es auch nicht ... ich habe ja das Projekt angefangen um meine eigenen Ideen umzusetzen. Bei Kundenprojekten muss ich leider auf Wunsch des selbigen auch der Mustermania verfallen.

Selber denken macht schlau, nicht blindes abkupfern.

Grüße
Alexander
Nicht gefallen, das sagte ich nicht ;) Momentan erfüllt sie halt noch nicht die von dir geforderten Anforderungen. Wollte dir nur eine Lösung präsentieren, wie ich sie angegangen wäre ;)

Selber denken macht schlau .. ja ... aber auch kucken wie es andere machen ... und warum :)

Gruß
schorsch

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 03.09.2011 22:04:31

Klar wenn sich die unterscheiden kann ich die nicht mehr in einer EventList haben aber das brauchts auch nicht.
Ich habe mich da mal selbst Zitiert macht man nicht ich weiss. Nur um nochmal darauf hinzuweisen das es nicht meine Anforderung war alle Event Typen in einer Liste zu haben.

Ich möchte Dir auch für Deine Vorschläge danken auch die sind Wertvoll zum gucken. :THX:
Wie auch das was die anderen C++ größen so tun. Da steckt viel gute Arbeit drin das sollte man nicht vergessen. Aber es wird meiner Meinung nach zu viel kritiklos einfach nachgemacht oder aus bequemlichkeit übernommen.
Das ist allgemein gemeint. Also nicht Du jetzt speziell also nicht böse sein. :hail:

Ich glaube mein Template kann das für mein Projekt besser. Die Zukunft wird zeigen ob ich recht hatte ...

Grüße
Alexander

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 24.09.2011 18:15:17

Jetzt hätte ich nochmal eine Frage: wenn man mit C++ Objekte erzeugt kann man das so

Code: Alles auswählen

  insertEvent xmlInsert;
oder so

Code: Alles auswählen

  insertEvent xmlInsert ();
tun.

Ich dachte eigentlich das ist das gleiche.
Leider hab ich da falsch gedacht der gcc sieht da einen Unterschied. Der will die zweite Version nicht per Pointer auf das Objekt weitergeben. Er meint dazu er sei ein non-static und dann geht das nicht. Klingt auf gccisch so:

Code: Alles auswählen

ExecXmlBauplan/ExecXmlBauplan.cpp:49: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say ‘&hts::ExecXmlBauplan::xmlInsert’
Grüße
Alexander

Benutzeravatar
schorsch_76
Beiträge: 2607
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von schorsch_76 » 24.09.2011 21:13:58

Laut Stroustrup "Die C++ Programmiersprache" Ausgabe 3 S.141:
Stroustrup hat geschrieben:Die Konstruktorschreibweise T() wird benutzt um den Defaultwert des Typs T darzustellen

Code: Alles auswählen

insertEvent xmlInsert ();
!=

Code: Alles auswählen

insertEvent xmlInsert;
Bsp.

Code: Alles auswählen

int() == 0
xmlInsert() versucht ein temporäres Objekt zu erzeugen vom Typ xmlInsert das mit den Defaultwerten konstruiert wird.

Gruß
schorsch

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 24.09.2011 21:28:44

Ja schon aber das tun doch beide Varianten oder?

Warum kann ich das zweite mit Klammer nicht per Pointer weitergeben?

Edit: Hab den Text im Buch auch gefunden. Die Konstruktion mit default Werten macht doch der Standardkonstruktor und der wird doch in beiden Fällen dann aufgerufen. Wenns keinen Standardkonstruktor gibt baut der Compiler selber einen. Es gibt noch die Variante mit einem Konstruktor mit Parametern dann muss aber für jeden Parameter ein default Wert definiert werden.

Benutzeravatar
schorsch_76
Beiträge: 2607
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von schorsch_76 » 24.09.2011 22:12:21

Klarstellung:Meine erste Erklärung war nicht korrekt:

Code: Alles auswählen

insertEvent xmlInsert;
erzeugt ein Objekt vom Typ insertEvent mit dem Namen xmlInsert;

Code: Alles auswählen

insertEvent xmlInsert();
Deklaration einer Funktion vom Namen xmlInsert mit Return Wert vom Typ insertEvent welche keine Argumente verlangt.
Das ruft _nicht_ den Defaultkonstruktor auf.

Siehe Stroustrup S153 ff

Das erklärt auch deine Fehlermeldung.



Gruß
schorsch

alexander_ro
Beiträge: 298
Registriert: 16.01.2006 17:44:21
Lizenz eigener Beiträge: GNU General Public License

Re: C++ in std::map Pointer auf Funktionsobjekte speichern

Beitrag von alexander_ro » 24.09.2011 22:24:54

Ja da is was dran.

Auch wenn die Fehlermeldung dazu ein bisschen ... wie soll man es schreiben ... verrückt ist ;-)

Edit: In dem Buch Seite 241 gibts da ein hübsches Beispiel dazu.

Wie benutzt man denn dann einen Konstruktor der einen Parameter hat. Sowas z.B.:

Code: Alles auswählen

insertEvent xmlInsert (pIntSeitenDb);
Da bekomme ich dann die gleiche Fehlermeldung und das sieht ja auch wie eine Funktionsdeklaration aus. Eigentlich will ich aber das Objekt mit dem entsprechenden Konstruktor erzeugen. Hmpf, irgendwie stehe ich glaube Grad ein wenig auf der Leitung ...

noch ein bisschen Editen ;-) :
Wenn man das auf ein dynamisches Objekt (new) umbaut dann funktioniert das. Habs Grad Probiert. Aber sowas müssen automatische Objekte doch auch können.

EDIT: Das geht so nicht oder? Weil ich ja das Objekt initialisieren will was man ja laut C++ an der stelle nicht darf. Wenn ich das in einer Memberfunktion mache kanns der Compiler übersetzen nur läuft dann das Programm nicht weil am Ende der Memberfunktion das Objekt zerstört wird und ich es noch benutzen will. In dem Fall bleibt eigentlich nur dynamisch (new) oder static weil man die auch außerhalb initialisieren darf. Was meinst Du seh ich das richtig ...

Antworten