Verschiedene Objekte in einem Vektor
-
Hier noch ein paar Hinweise, die man sich später mal anschauen sollte:
- Command-Pattern http://de.wikipedia.org/wiki/Command_Pattern
- Function http://www.boost.org/doc/html/function.html (aka Delegates-Pattern)Diese dienen dafür, z.B. play aufzurufen, OHNE den Player speziell zu kennen!!! Aber es ist kein Cast nötig!!!
Würde ich mich aber erst mit beschäftigen, wenn ich etwas mehr Erfahrung mit eigenen "Kreationen" gesammelt habe. Weil dann wird man erst diese Patterns zu schätzen wissen und man erkennt die Probleme die man damit löst.

-
Artchi schrieb:
play kann der jenige aufrufen, der den Player kennt. Oder sich über einen Callback oder Delegate diesen indirekt merkt. Dein Denkfehler ist, das du auf einen Player speziell zugreifen willst, obwohl du ihn nicht kennst. Das ist so, als wenn du in einem Polizeiauto die Sirene einschalten willst, obwohl du garkein Polizeiauto kennst oder vor dir stehen hast. Du willst anscheinend über Magie etwas tätigen, was völlig unmöglich ist.
Wo genau ist da der Denkfehler? Wenn meine Fensterklasse funktionen bietet um über GuiBasisElement* zu itererieren. Was ist daran auszusetzten dass ich so auf den Player dann auch zugreife?
Noch zusätzlich irgenwelche Zeiger zu speichern ist rendundant und kann Fehler verursachen. (Mein Player wird ohne meine Kenntnis durch einen anderen ersetzt.) Natürlich kann ich für alle möglichen Fälle Callbacks und co. anbieten. Aber warum sich unnötig arbeit machen, wenn ein einfacher dynamic_cast ausreicht?Wie programmierst du denn normalerweise? Du hast ein spezielles Objekt angelegt (den Player), weil du mit diesem etwas spezielles machen willst.
Ich habe ja im letzten Absatz geschrieben, dass das Fenster aus einer XML-Datei erstellt wird. Die Xml-Datei wurde mit irgendeinem GUI-Editor angelegt. Ok, ich kann da callbacks beim laden zwischenschalten und so auf einen pointer kommen. aber dazu siehe oberen absatz.
Ich glaube, hier liegt der Irrtum vor, das nur der Container die GUI-Elemente kennen soll.
Wenn es dir darum geht, das der Movieplayer vom User bedient werden soll: der Player kümmert sich selber um seine Play-Buttons. Drückt der User mit der Mouse drauf, reagiert der PlayButton selbst (genauso wie er sich auch selber zeichnet!).
Naja, der Player kann nicht alle Möglichkeiten abdecken, wie ihn der Benutzer verwendet. Der kann auf Player direkt klicken. Ok, den Fall braucht man nicht weiter zu betrachten. Der Player kann hier selbst dafür sorgen, dass er diese Aktionen wahrnimmt.
Aber wenn ich meinen Player übers Netzwerk steuern will. will ich das mehr oder weniger direkt über player::play() machen. und nicht die maus dort positionieren, wo sich das entsprechende button befindet.Das sind halt Erfahrungen, die man sammelt. Meistens ist die Sache einfacher und logischer als man denkt.
Ich habe den eindruck, dass du denks, dass ich noch neu in der programmierung bin. aber ich programmiere schon seit 8 jahren c++.
obwohl..., das muss nichts aussagen.

-
Wenn meine Fensterklasse funktionen bietet um über GuiBasisElement* zu itererieren. Was ist daran auszusetzten dass ich so auf den Player dann auch zugreife?
Warum soll das Fenster (bitte darüber nachdenken!) die Play-Methode aufrufen wollen? WAS hat das Fenster mit dem Play zutun? Das Fenster kennt nur das GuiBasisElement-Interface.
Noch zusätzlich irgenwelche Zeiger zu speichern ist rendundant und kann Fehler verursachen. (Mein Player wird ohne meine Kenntnis durch einen anderen ersetzt.)
Nein, ebend nicht! Denn dein Pointer ist private! (man soll es nicht glauben) Meinetwegen machste halt keinen Pointer:
class Anwendung { MeinAppleQuickTimePlayer player; // kein Pointer Fenster fenster; public: Anwendung() { fenster.add(&player); // allgemein } };Das mit der Redundanz ist kein Argument. Wir reden hier über OO-DESIGN und nicht über "Wie spare ich 4 Byte?".
Aber wenn ich meinen Player übers Netzwerk steuern will. will ich das mehr oder weniger direkt über player::play() machen. und nicht die maus dort positionieren, wo sich das entsprechende button befindet.
Auch dann kennt dein Netzwerk-CLient ein bestimmtes Interface. (selbst wenn es nur ein bestimmter String-Schlüssel ist) Es kann ein Wrapper sein, der am anderen Ende der Leitung wieder die play-Methode kennt. (z.B. durch erkennung des String-Schlüssels)
Ich stelle fest, das du immer wieder andere Ausnahme-Szenarios vorbringst, sobald ich dir eine Nicht-Cast-Lösung aufzeige. Komisch, oder?
Deine 8 Jahre sind schön und gut. Aber 1. lernt man nie aus. Und 2. sind gerade alte C++-Programmierer nicht DIE C++-Profis. Wenn ich sehe, das Projekte immer noch auf VC6 rumgurken und NICHT auf VC8 umsteigen können, weil sie nicht sauber C++ programmiert haben, sagt mir das sehr viel.
Ich kenne dich überhaupt nicht, deshalb ist mein vorheriger Absatz allgemein gesprochen. Und das du C++-Neuling bist, muß ich davon ausgehen, da du nicht registriert bist, und somit keine Infos über dich habe.
-
Artchi schrieb:
Warum soll das Fenster (bitte darüber nachdenken!) die Play-Methode aufrufen wollen? WAS hat das Fenster mit dem Play zutun? Das Fenster kennt nur das GuiBasisElement-Interface.
Ich habe nie behauptet, dass ich auf die Play-Methode innerhalb der Fenster-Klasse zugreiffe. Das Fenster bietet Methoden um über die Elemente zu iterieren.
Noch zusätzlich irgenwelche Zeiger zu speichern ist rendundant und kann Fehler verursachen. (Mein Player wird ohne meine Kenntnis durch einen anderen ersetzt.)
Nein, ebend nicht! Denn dein Pointer ist private! (man soll es nicht glauben) Meinetwegen machste halt keinen Pointer:
class Anwendung { MeinAppleQuickTimePlayer player; // kein Pointer };Das mit der Redundanz ist kein Argument. Wir reden hier über OO-DESIGN und nicht über "Wie spare ich 4 Byte?".
Bei Redundanz geht es mir nicht so sehr 4 bytes einzusparen, sondern um den zusätzlichen Aufwand um Sicherzustellen, dass der zeiger IMMER auf ein gültiges Objekt verweist.
Auch dann kennt dein Netzwerk-CLient ein bestimmtes Interface. (selbst wenn es nur ein bestimmter String-Schlüssel ist) Es kann ein Wrapper sein, der am anderen Ende der Leitung wieder die play-Methode kennt. (z.B. durch erkennung des String-Schlüssels)
Gegen Schlüssel jeglicher Art bin ich ziemlich alergisch. Sie erfordern abwärtskompatibilität. Vor allem, wenn man Komponenten von 3. herstellern verwendet. Ich will aber nicht abwärtskompatibel sein. Will auch jederzeit die schlüssel ändern können, wenn ich lustig danach bin.
Ich stelle fest, das du immer wieder andere Ausnahme-Szenarios vorbringst, sobald ich dir eine Nicht-Cast-Lösung aufzeige. Komisch, oder?
Ich muss ja meine Argumentation.... verteitigen.
Ich versuche halt so zu programmieren, dass selbst die abwegigsten Ausnahme-Szenarien umgesetzt werden können.
-
frager schrieb:
Gegen Schlüssel jeglicher Art bin ich ziemlich alergisch. Sie erfordern abwärtskompatibilität. Vor allem, wenn man Komponenten von 3. herstellern verwendet. Ich will aber nicht abwärtskompatibel sein. Will auch jederzeit die schlüssel ändern können, wenn ich lustig danach bin.
Habe vergessen dazu zu sagen, dass ich zusätzliche Typinformationen nicht toll finde.
-
Bei Redundanz geht es mir nicht so sehr 4 bytes einzusparen, sondern um den zusätzlichen Aufwand um Sicherzustellen, dass der zeiger IMMER auf ein gültiges Objekt verweist.
Dann nimmst du Smartpointer, wie z.B. std::tr1::shared_ptr. Hat aber nichts mit OOD zu tun, sondern mit C++-Technik. Aber es gibt zu allem saubere Lösungen. Hat aber letzendlich nichts mit Castst zutun?
Habe vergessen dazu zu sagen, dass ich zusätzliche Typinformationen nicht toll finde.
Ehm, und dynamic_cast benötigt keine Typinformationen?
dynamic_cast arbeitet intern sicherlich mit Strings. 
Naja, wenn du deine alten und (in meinen Augen) falschen Argumente _verteidigen_ mußt oder willst, breche ich hier meine Thread-Beteiligung ab. Denn das ist nicht gerade eine Basis, jemandem HELFEN zu können, der es nicht verstehen will.
-
Artchi schrieb:
Ehm, und dynamic_cast benötigt keine Typinformationen?
dynamic_cast arbeitet intern sicherlich mit Strings. 
Diese Typinformationen sind schon eingebaut. Ich hoffe es würde auch keiner auf die Idee kommen type_info::name() zum verwenden um persistente daten typen zuzuordnen.
Naja, wenn du deine alten und (in meinen Augen) falschen Argumente _verteidigen_ mußt oder willst, breche ich hier meine Thread-Beteiligung ab. Denn das ist nicht gerade eine Basis, jemandem HELFEN zu können, der es nicht verstehen will.
Sorry, falls du mich falsch verstanden hast. Ich lasse mich gerne des besseren belehren. Bloß in meinen Augen sieht so aus, dass bei der alternative zu dynamic_cast eine unmenge an arbeit (== potentielle bugs) dahintersteckt. Dass ich durch diese zusätzlichen Aufwand etwas gewinne (vermeintlich besseres Objektorientiere-Design, nehme ich an), davon hast du mich noch nicht so recht überzeugt.
-
Zwischenmenschliche Kommunikation ist für mich eine komplizierte Sache. U.a. weil Deutsch nicht meine Muttersprache ist. Es enstehen dann immer solche "Kommukationsfehler" wo ich nicht recht weiß warum mich der andere nicht verstanden hat.
So als anmerkung...