Instanzierung eines Singeltons bei Templates

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Instanzierung eines Singeltons bei Templates

    Zur Zeit versuche ich, ein rein Text basiertes C++ Projekt sowohl unter der Mac Xcode Umgebung als auch unter Microsoft Visual Studio (worunter es klappt) zur Compilation und zum Laufen zu bringen.

    Bei der Verwendung von Templates scheint es nun aber formale Unterschiede zu geben bei der Definition der Instanziierung statischer Singleton-Instanzen zu einer parametrisierten Klasse.

    Ist das Problem bekannt? Wo findet man Näheres dazu?
    Dem 10x8-Schach gehört die Zukunft !
  • Nun, ich deute das mal so, dass man mehr Details sehen möchte. Also versuche ich hier, den Sachverhalt auf ein kleines Beispiel zu reduzieren:

    Figuren.h

    Quellcode

    1. namespace Octopus {
    2. // einfache Datentypen
    3. typedef unsigned char TCol; // Farbe
    4. // die zwei Farb-Indizes
    5. const TCol Ws = 0; // weiß
    6. const TCol Sw = 1; // schwarz
    7. // === Schach-Singleton in beiden Farben ===
    8. template <const TCol col> class S {
    9. public:
    10. // Farb-Eigenschaften
    11. static const char FarbSymbol = (col == Ws) ? 'w' : 'b';
    12. private:
    13. // geschützter Konstruktor
    14. S(void);
    15. // geschützter Destruktor
    16. ~S(void);
    17. // geschützte Singleton Inkarnation
    18. static S Single;
    19. public:
    20. // TODO: Testfunktion
    21. static inline char test() { return FarbSymbol; };
    22. };
    23. } // Ende Namespace Octopus
    Alles anzeigen

    Figuren.cpp

    Quellcode

    1. #include "Figuren.h"
    2. using namespace Octopus;
    3. // verborgene Singleton Inkarnationen
    4. S<Ws> S<Ws>::Single; // erlaubt Weiß
    5. S<Sw> S<Sw>::Single; // erlaubt Schwarz
    6. // verborgener Konstruktor Singleton
    7. template <const TCol col> S<col>::S(void)
    8. {
    9. }
    10. // verborgener Destruktor Singleton
    11. template <const TCol col> S<col>::~S(void)
    12. {
    13. }
    Alles anzeigen

    Main.cpp

    C-Quellcode

    1. #include <iostream>
    2. using namespace std;
    3. #include "Figuren.h"
    4. using namespace Octopus;
    5. int main (int argc, char * const argv[]) {
    6. // insert code here...
    7. cout << S<Ws>::test() << endl;
    8. cout << S<Sw>::test() << endl;
    9. return 0;
    10. }
    Alles anzeigen


    Die Zeilen 6 und 7 in Figuren.cpp werden unter Xcode leider nicht akzeptiert und erzeugen:
    error: too few template-parameter-lists


    Ich weiß, dass sich C++ Compiler bei der Bereitstellung von komplexeren, Template gesteuerten statischen Strukturen nicht unbedingt einheitlich in Bezug auf die Syntax verhalten. Es wäre schön, auch Xcode zum Anlegen dieser beiden Singleton Inkarnationen bewegen zu können.
    Dem 10x8-Schach gehört die Zukunft !
  • Danke soweit. Tatsächlich gab mir das Anregung zu folgender (zwischen Xcode und Visual Studio portablen) Lösung, welche die beiden problematischen Zeilen erfolgreich ersetzt:

    Quellcode

    1. #ifdef __GNUC__
    2. #define TMPL(x) template <x>
    3. #else
    4. #define TMPL(X) /* */
    5. #endif
    6. // verborgene Singleton Inkarnationen
    7. TMPL(const TCol col) S<Ws> S<Ws>::Single; // erlaubt Weiß
    8. TMPL(const TCol col) S<Sw> S<Sw>::Single; // erlaubt Schwarz
    Dem 10x8-Schach gehört die Zukunft !
  • Leider muss ich hier vorerst aufgeben. Es scheinen unter Xcode einfach keine statischen Singleton Inkarnationen von Templates erzeugt zu werden. Beim Link kracht es dann also.

    Quellcode

    1. ZeroLink: unknown symbol '__ZN7Octopus1SILh1EE6SingleE'
    2. Octopus has exited due to signal 6 (SIGABRT).
    Dem 10x8-Schach gehört die Zukunft !
  • Original von Scharnagl
    Nun, ich deute das mal so, dass man mehr Details sehen möchte. Also versuche ich hier, den Sachverhalt auf ein kleines Beispiel zu reduzieren:

    Also, wenn ich diesen "Code" sehe sei Dir ein gutes Buch (C++ Templates, The Complete Guide, Vandevoorde, Josuttis) über Template Programmierung empfohlen, es sind eine ganze Reihe Fehler drin. Erstens das ist keine Template Klasse sondern irgend ein Kraut&Rüben durcheinander. Zweitens Templates lassen sich nur über Typen spezialisieren und nicht über Werte.

    Eine mögliches Design was sich an Deinen Eckpunkten orientiert.

    Figuren.h

    Quellcode

    1. namespace Octopus {
    2. // einfache Datentypen
    3. typedef unsigned int TCol; // Farbe
    4. class weiss {
    5. static TCol const value_;
    6. public:
    7. TCol static value () {return value_;}
    8. };
    9. class schwarz {
    10. static TCol const value_;
    11. public:
    12. TCol static value () {return value_;}
    13. };
    14. // === Schach-Singleton in beiden Farben ===
    15. template <typename T> class S {
    16. S() {};
    17. S (S const&);
    18. ~S() {};
    19. S& operator= (S const&);
    20. static S* p_;
    21. public:
    22. static S& instance () {
    23. if (0 == p_) {
    24. p_ = new S;
    25. }
    26. return *p_;
    27. };
    28. // TODO: Testfunktion
    29. TCol static test () {return T::value();}
    30. };
    31. } // Ende Namespace Octopus
    Alles anzeigen


    Figuren.cc

    Quellcode

    1. #include "Figuren.h"
    2. using namespace Octopus;
    3. TCol const weiss::value_ = 0;
    4. TCol const schwarz::value_ = 1;
    5. template<> class S<weiss>* S<weiss>::p_ = 0;
    6. template<> class S<schwarz>* S<schwarz>::p_ = 0;


    main.cc

    C-Quellcode

    1. #include <iostream>
    2. using namespace std;
    3. #include "Figuren.h"
    4. using namespace Octopus;
    5. int main () {
    6. cout << S<weiss>::test() << endl;
    7. S<weiss>::instance();
    8. }
    Alles anzeigen


    Edit:
    So jetzt läßt sich das Ding auch instanzieren.
  • Original von tjpAlso, wenn ich diesen "Code" sehe sei Dir ein gutes Buch (C++ Templates, The Complete Guide, Vandevoorde, Josuttis) über Template Programmierung empfohlen, es sind eine ganze Reihe Fehler drin.

    Einmal davon abgesehen, dass der Code vornehmlich den Zweck hatte, ein abweichendes Compilerverhalten herauszustellen, funktioniert er unter Visual C++ einwandfrei und lässt sich (nach der beschriebenen Ergänzung) auch unter Xcode fehlerfrei kompilieren.

    Original von tjp: das ist keine Template Klasse sondern irgend ein Kraut&Rüben durcheinander.

    Entweder ist das von Dir empfohlene Buch unvollständig, oder Du hast es nicht ganz gelesen. Wie man z.B. bei Aupperle: "Die Kunst der objektorientierten Programmierung mit C++" auf Seite 715 zur Syntax von Templates nachlesen kann: ... "Die Argumente müssen nicht (wie bei Funktionsschablonen) unbedingt Typen sein. Möglich sind ebenso Variablennamen, Funktionsnamen oder konstante Ausdrücke. Besonders oft werden numerische Größen verwendet:" ...

    Original von tjp: Zweitens Templates lassen sich nur über Typen spezialisieren und nicht über Werte.

    Das sehen offenbar die Fachleute etwas anders.

    Original von tjp: Ein mögliches Design was sich an Deinen Eckpunkten orientiert. ...

    Da es mir mehr um das abweichende Compilerverhalten ging als um die Propagierung irgendeines Entwurfmusters, habe ich meine Intentionen gar nicht näher beschrieben. So wundert es nicht, dass Dein Vorschlag wenig damit harmoniert.

    Möglicherweise war durch den Kontext "Schachprogrammierung" noch nicht klar genug, dass es mir hier um performante Lösungen geht. Insofern kann ich keine dynamisch erzeugten Singleton-Inkarnationen gebrauchen. Jeder Zugriff hätte so eine Indirektion zuviel. Außerdem kann ich mich statisch erzeugt jederzeit auf die Existenz der Singletons verlassen.

    Mein Entwurf verwendet also statische Singletons, bei dessen Definition (in der *.cpp Datei) eben diese Compiler-Unterschiede auftauchen, die ich abklären wollte. Außerdem wollte ich definitiv vermeiden, zwei Klassen für Weiß und Schwarz per Namen zu deklarieren, sondern ich wollte das eben per einem Template erledigen.

    Und wieso man zum Verwenden einer zur Kompilierungszeit bekannten Konstanten einer Klasse eine Getter-Funktion benötigt, erschließt sich mir auch noch nicht recht.
    Dem 10x8-Schach gehört die Zukunft !
  • Die Klasse S wie hier dargestellt ist kein Singleton! Ein statisches Interface macht noch kein Singleton. Es gibt keinerlei Möglichkeit auf die Instanz von S zuzugreifen, S ließe sich kopieren usw. Da bedarf es dringend einer Überarbeitung, entweder zu einer Klasse mit rein statischem Interface oder zu einem Singleton. Wenn das ganze Design überdacht wird, erschließt sich einem auch, warum es zu diesem Compilerproblem kam.

    Ja, Template-Klassen kann man mit Compilezeit Konstanten spezialisieren, aber dann sollte dies auch durch das Design wiedergespiegelt werden.

    Die "Lösung" ist ein Hack, von jemanden, der die korrekte Syntax für die Bezeichnung von Templates nicht kennt. Templates sind nun einmal nicht mehr so exsotisch, daß man hier bedingte Compilierung einsetzen müßte, damit der Code sowohl unter MacOS X wie auch Windows compiliert. Also anstatt des Makros sollte man doch besser den Code zu verwenden:
    Sollte man doch besser

    Quellcode

    1. template<> class S<weiss> S<weiss>::Single;
    2. template<> class S<schwarz> S<schwarz>::Single;
  • Die Klasse lässt sich nicht kopieren, da es keinen öffentlichen Konstruktor gibt. Außerdem scheiterte jeder Bezug auf statische Elemente einer versehentlichen hypothetischen weiteren Template-Realisierung, weil kein namentlich passender statischer Speicherplatz gefunden werden kann. Ein Link dazu wäre unmöglich. Insofern haben die beiden kodierten statischen Speicher zugleich eine filternde Kontrollfunktion.

    Das hier vorgestellte Design als solches ist vollkommen nebensächlich, ob ich es für meine Zwecke gut finde oder nicht. Es ging mir allein um das Herausarbeiten eines unterschiedlichen Compiler- und Linker-Verhaltens. Ich habe kein Allzweckmodell propagieren wollen.

    Leider ist es bei der Anlage von statischen Speicherbereichen von Templates eben nicht gleichgültig, welchen Compiler man verwendet. Dein Lösungsvorschlag besteht letzten Endes darin, darauf völlig zu verzichten, und ist so eben keine Lösung zum geschilderten Problem.

    Stattdessen fokussierst Du Dich schulmeisternd auf mein Entwurfsmuster, wirfst mir Fehler vor, die außer Dir kein Compiler zu entdecken vermag. Ich habe hier kein Modellprogramm zur Diskussion gestellt, sondern erbat mir eine Lösung zu diesem spezifischen unerquicklichen Compiler/Linker-Verhalten unter Xcode.

    Was mein Rewrite des 8x8 und 10x8 Schachprogramms SMIRF als Octopus angeht, so teste ich eine ganze Reihe verschiedener Entwurfsmuster aus, um eben zweierlei zu erreichen: Performanz und plattformübergreifende Kompilierbarkeit. Da Letzteres in der geposteten Form unter Xcode nicht zum Erfolg zu bringen ist (unter Visual Studio klappte übrigens alles einwandfrei), ist diese Form ohnehin gestorben.

    Ich habe nichts dagegen, wenn Du in Deinen Kodierungen Templates nicht auf Konstanten basierst. Lass aber mir die Freiheit, es anders zu tun, so wie es der Sprachstandard erlaubt. Im Gegensatz zu Dir werde ich damit auch kein Missionierungswerk starten.
    Dem 10x8-Schach gehört die Zukunft !
  • Als erstes sollte vor allem ein Punkt geklärt werden, ein Singleton ist ein feststehendes Entwurfsmuster, das sich nach "Design Patterns, Elements of Reusable Object-Oriented Software; Gamma, Helm, Johnson, Vlissides" durch folgenden Eigenschaften auszeichnet:
    • Es gibt nur ein Exemplar.
    • Es gibt nicht nur Klassenvariablen und Klassenmethoden in der Klasse.
    • Zugriff auf das Exemplar via einer Klassenmethode.

    Weder das eine noch das andere ist bei deiner Klasse der Fall. Ergo, ist es kein Singleton.

    Original von Scharnagl
    Die Klasse lässt sich nicht kopieren, da es keinen öffentlichen Konstruktor gibt.

    Guter Witz, noch nie etwas vom CopyConstructor gehört? Mit dem kann man Objekte kopieren, siehe dazu Beispielcode.

    Figure.h

    C-Quellcode

    1. #ifndef FIGURE_H
    2. #define FIGURE_H
    3. #include <ostream>
    4. #include <iostream>
    5. typedef unsigned char TCol; // Farbe
    6. // die zwei Farb-Indizes
    7. TCol const weiss = 'w'; // wei?~_
    8. TCol const schwarz = 's'; // schwarz
    9. // === Schach-Singleton in beiden Farben ===
    10. template <TCol const col> class S {
    11. static S Single;
    12. S () : Farbsymbol (col) {}
    13. ~S () {}
    14. char Farbsymbol;
    15. public:
    16. static S& instance () {return Single;}
    17. char test() const {return this->Farbsymbol;};
    18. void setFarbe (char const s) {this->Farbsymbol = s;}
    19. };
    20. // dient nur dazu, daß der falsche Code sich linken läßt
    21. template<TCol const col> class S<col> S<col>::Single = S<col> ();
    22. // eigentliche Spezialisierung
    23. template<> class S<weiss> S<weiss>::Single = S<weiss>();
    24. template<> class S<schwarz> S<schwarz>::Single = S<schwarz>();
    25. #endif
    Alles anzeigen


    main.cc

    C-Quellcode

    1. include <iostream>
    2. using namespace std;
    3. #include "Figure.h"
    4. int main (int argc, char * const argv[]) {
    5. S<weiss>& wi(S<weiss>::instance());
    6. S<schwarz>& si(S<schwarz>::instance());
    7. // Oh Wunder, Oh Wunder eine Kopie, wer hätte das gedacht!
    8. S<weiss>* p = new S<weiss>(wi);
    9. // damit auch ein jeder sieht, daß es eine Kopie ist
    10. p->setFarbe('x');
    11. // Ausgabe der Farbsymbol Werte
    12. cout << wi.test() << endl;
    13. cout << si.test() << endl;
    14. // Das dürfte nach dir ja nicht passieren.
    15. cout << p->test() << endl;
    16. // und das schon gar nicht
    17. wi = *p;
    18. cout << wi.test() << endl;
    19. // nächstes Problem
    20. S<'l'>& x (S<'l'>::instance());
    21. cout << x.test() << endl;
    22. // wenn die S<>::Single nur spezialisiert definiert wird, gibt es Linkerfehler
    23. // So wie ich das hier gemacht habe compiliert es anstandslos durch
    24. // Obwohl es nicht sinnvoll ist.
    25. // Wenn man sich für KonstantenInstanzierung entscheidet, dann sollte das auch
    26. // für alle Werte des Typ innvoll sein. Sonst ist die Variante via Klassen
    27. // sauberer.
    28. }
    Alles anzeigen



    Original von Scharnagl
    Das hier vorgestellte Design als solches ist vollkommen nebensächlich, ob ich es für meine Zwecke gut finde oder nicht. Es ging mir allein um das Herausarbeiten eines unterschiedlichen Compiler- und Linker-Verhaltens.

    Das Design und der Code sind maßgeblich für die Probleme beim Compilieren und Linken. Das Linkerproblem wird durch das Design überhaupt aufgeworfen. Dein Problem ist, daß du zwar einen statischen member deklarierst in aber nicht definierst und dabei notwendigerweise initialisierst.
    Original von Scharnagl
    Leider ist es bei der Anlage von statischen Speicherbereichen von Templates eben nicht gleichgültig, welchen Compiler man verwendet.

    Falsch, man muß es nur richtig machen, dann geht das auch. Es sei hier auf die relevante ISO Norm 14882:2003 verwiesen. Alternativ kann man auch bei groups.google.com im Archiv von comp.lang.c++.moderated nachlesen bzw. posten. Einige der Mitautoren an der ISO Norm posten dort regelmäßig.
    Original von Scharnagl
    Dein Lösungsvorschlag besteht letzten Endes darin, darauf völlig zu verzichten, und ist so eben keine Lösung zum geschilderten Problem.

    Du mußt Dich entscheiden, ob Du ein Singleton willst, dann ist den Entwurf falsch oder ob es eine Template Klasse ausschließlich mit statischen member functions und membern willst. Auch unter dieser Maßgabe ist dein Entwurf schlecht. Einen Singleton Lösungansatz, der plattform neutral ist, habe ich Dir bereits gepostet. Was Du gemacht hast, ist irgend ein suboptimaler Mix aus beiden, der weder das eine noch das andere ist.

    Was den Lösungsansatz betrifft. Ich habe in meine Beispiel die korrekte Syntax für die Definition und Initialisierung der statischen Member in der Spezialisierung benutzt, die schlußendlich für das Linkerproblem bei dir verantwortlich war.
    Original von Scharnagl
    Stattdessen fokussierst Du Dich schulmeisternd auf mein Entwurfsmuster, wirfst mir Fehler vor, die außer Dir kein Compiler zu entdecken vermag.

    Das Forum ist öffentlich, da mußt du mit Kritik leben, ob dir das nun paßt oder nicht. Jedenfalls gibt es einen Diskrepanz zwischen dem Begriff Singleton und deinem Code. Ein Compiler ist nicht in der Lage dein Design zu prüfen. Ich möchte hierbei noch erinnern wessen Code Probleme aufwarf. Probleme dieser Art löst man nicht in dem man aus reinem Narzißmus irgend wie mit einem Makro am Code herumpfuscht solange es compiliert. Und die Aussage compiliert mit Compiler X ist nahezu bedeutungslos. Wenn sich das wenigstens auf den Comeau-Compiler bezogen hätte, dann wäre die Aussage wenigstens halbwegs was wert, aber so …
  • Nun, man kann in meinem Beispiel alles verbasteln, wenn man will - z.B. wenn man direkt oder indirekt öffentliche Konstruktoren einfügt. Das hat aber dann mit meinem Code nur noch wenig zu tun.

    Und Deine Beiträge gehen nach wie vor an der von mir aufgeworfenen Frage vorbei. Ich habe kein Interesse daran, hier über Entwurfsmuster zu diskutieren. Mache doch einfach dazu einen eigenen Thread auf, falls das Dir so wichtig ist. Denn bei den geschilderten anderen Verhaltensweisen von Xcode und Visual Studio hilft es hier effektiv nicht weiter.

    Für meine Form von Singletons (oder gelegentlich auch Twintons) habe ich eben meine Gründe, und deren Form hat sich für mich, wo sie sinnvoll eingesetzt waren, bislang bewährt. Und niemand braucht sich daran zu stoßen, denn ich plakatiere sie nicht. Und ich rege mich nicht über Deine vielleicht sogar gut gemeinte Kritik an meinem Code auf, sondern darüber, dass sie komplett an meiner Fragestellung vorbei geht, und dass sie in einem unpassend überheblichen Ton abgefasst ist.
    Dem 10x8-Schach gehört die Zukunft !
  • RE: Instanzierung eines Singeltons bei Templates

    Ein kleiner Widerspruch in sich, findest du nicht?

    Original von Scharnagl
    Bei der Verwendung von Templates scheint es nun aber formale Unterschiede zu geben bei der Definition der Instanziierung statischer Singleton-Instanzen zu einer parametrisierten Klasse.

    Original von Scharnagl
    Für meine Form von Singletons (oder gelegentlich auch Twintons) habe ich eben meine Gründe, und deren Form hat sich für mich, wo sie sinnvoll eingesetzt waren, bislang bewährt.


    Willst du jetzt eine Singleton-Instanz haben oder eine eigene Twintons-Instanz?

    Die eigentlichen Singletons funktionieren so wie von tjp beschrieben.
    Wenn die Twintons nicht laufen wird es wohl an den Twintons liegen.

    Warum laufen wohl diverse andere Entwurfsmuster unter Visual C++, nicht aber mit dem GPP?
    Weil irgend ein Windows-spezifischer Ansatz gewählt wurde der unter dem GPP so nicht läuft.

    Der Visual C++ versteht dein Twinton offenbar, der GPP hält es für ein Singleton, welches falsch benutzt wurde.

    Wer etwas ohne großartige Designänderung für Windows und Mac erstellen will, der bekommt automatisch derartige Probleme.
    Augenscheinlich hat der GPP keine Ahnung, was mit [font="courier new"]S<Ws> S<Ws>::Single;[/font] gemeint sein könnte. Ich übrigens auch nicht.

    (Persönliche Meinung, nur zur allgemeinen Belustigung: Sinn und Verstand von Templates hat sich mir noch nie offenbart - was soll dieser Blödsinn eigentlich? Hätte man doch gleich richtig machen können...)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Original von Scharnagl
    Und ich rege mich nicht über Deine vielleicht sogar gut gemeinte Kritik an meinem Code auf, sondern darüber, dass sie komplett an meiner Fragestellung vorbei geht, und dass sie in einem unpassend überheblichen Ton abgefasst ist.

    Wenn du nicht so borniert wärest, und dich einmal mit meinen Antworten und deinem Problem grundlegend auseinandersetzen würdest, da sähest du auch, daß das Design Ursache der Probleme ist. So neben bei die richtigen Syntax, deinen Murks zu übersetzen habe ich auch schon gepostet.

    P.S. Dein Problem läßt sich banal so lösen, ohne daß es in deinem Beispiel zu irgend einer Einschräkung der Funktionalität kommt. Man muß halt wissen was man tut, und nicht blindlings ohne Verständnis drauflos hacken.

    Figuren.h

    Quellcode

    1. typedef unsigned char TCol;
    2. const TCol Ws = 0;
    3. const TCol Sw = 1;
    4. template <const TCol col> class S {
    5. S(void);
    6. ~S(void);
    7. public:
    8. static inline char test() { return FarbSymbol; };
    9. static const char FarbSymbol = (col == Ws) ? 'w' : 'b';
    10. };
    Alles anzeigen


    main.cc

    C-Quellcode

    1. #include <ostream>
    2. #include <iostream>
    3. #include "Figuren.h"
    4. int main () {
    5. std::cout << S<Ws>::test() << std::endl;
    6. std::cout << S<Sw>::test() << std::endl;
    7. }
  • Hmm, da hört jemand den Schuss nicht:

    a) Nicht tjp, sondern du hast den Begriff Singleton eingeführt und zwar von Anfang an und ihn wiederholt verwendet. Lösch mal alle deine Beiträge, die den Begriff Singleton enthalten. Na, was bleibt übrig?

    b) Nicht tjp, sondern du hast den Begriff falsch verwendet. So weit ich das sehe, willst du einen Multiton. Allerdings habe ich ob des Begriffswirrwarrs auch Probleme deinen Beiträgen zu folgen. Begriffe sind Schall und Rauch – aber sie erleichtern die Kommunikation ungemein.

    c) Nicht der Compiler (Linker), sondern du machst etwas falsch. Das hat dir tjp auseinander gedröselt. Es ist müßig zu diskutieren, warum fehlerhafter Code auf verschiedenen Compilern zu unterschiedlichen Verhalten führt und welcher der Compiler dann etwas falsch macht. Beseitige deinen Fehler!
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • RE: Instanzierung eines Singeltons bei Templates

    Original von Lucas de Vil
    (Persönliche Meinung, nur zur allgemeinen Belustigung: Sinn und Verstand von Templates hat sich mir noch nie offenbart - was soll dieser Blödsinn eigentlich? Hätte man doch gleich richtig machen können...)

    Da stellt sich doch die Frage was Du unter richtig machen verstehst?
    Der Sinn zum Beispiel eines generischen Containers gegenüber einem polymorphen Containers ist es, daß man in diesen Container eben nur Objekte eines bestimmten Typ ablegen kann.
    C++ Beispiel:

    Quellcode

    1. include<vector>
    2. class A {};
    3. int main () {
    4. std::vector<int> v(100); // vector mit 100 ints erzeugen
    5. std::vector<A> a(100), b(10); // vector mit 100 As erzeugen
    6. // folgendes ist zulässig
    7. A ein_A;
    8. a = b;
    9. v[0] = -5;
    10. a[0] = ein_A;
    11. // folgendes führt jeweils zu einem Compilefehler
    12. v = a;
    13. a[0] = -5;
    14. v[0] = ein_A;
    15. }
    Alles anzeigen
  • RE: Instanzierung eines Singeltons bei Templates

    Original von tjp

    Quellcode

    1. // folgendes führt jeweils zu einem Compilefehler
    2. v = a;
    3. a[0] = -5;
    4. v[0] = ein_A;
    5. }


    Original von Lucas de Vil


    Hätte man doch gleich richtig machen können...)


    Genau.
    I would be embarrassed if they did not spy on me.
  • RE: Instanzierung eines Singeltons bei Templates

    Original von tjp
    Original von Lucas de Vil
    (Persönliche Meinung, nur zur allgemeinen Belustigung: Sinn und Verstand von Templates hat sich mir noch nie offenbart - was soll dieser Blödsinn eigentlich? Hätte man doch gleich richtig machen können...)

    Da stellt sich doch die Frage was Du unter richtig machen verstehst?
    Der Sinn zum Beispiel eines generischen Containers gegenüber einem polymorphen Containers ist es, daß man in diesen Container eben nur Objekte eines bestimmten Typ ablegen kann.


    Und wo liegt da jetzt der Unterschied zum polymorphen Container, in den man nur Objekte eines bestimmten Typs ablegen will?

    Quellcode

    1. NSArray* stringArray = [NSArray array];
    2. NSArray* numberArray = [NSArray array];
    3. NSString* sinnloseKette = @"Hallo Welt!";
    4. NSNumber* doofeNummer = [NSNumber numberWithInt:1];
    5. [numberArray addObjects: doofeNummer, doofeNummer, sinnloseKette, nil];
    6. [stringArray addObjects: sinnloseKette, sinnloseKette, doofeNummer, nil];
    7. id object;
    8. foreach( object in numberArray) {
    9. NSLog(@"Number: %d", [object intValue]);
    10. }
    11. foreach( object in stringArray) {
    12. NSLog(@"String: %@", [object stringValue]);
    13. }
    Alles anzeigen


    Number: 1
    Number: 1
    Number: 0
    String: Hallo Welt!
    String: Hallo Welt!
    String: 1


    Klar, der Compiler meckert nicht und man sucht sich blöd nach dem Fehler.

    Resultat unterschiedlich, Ursache dieselbe:
    Original von Lucas de Vil

    Hätte man doch gleich richtig machen können...
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • RE: Instanzierung eines Singeltons bei Templates

    Original von Lucas de Vil
    Und wo liegt da jetzt der Unterschied zum polymorphen Container, in den man nur Objekte eines bestimmten Typs ablegen will?

    Der Unterschied liegt darin, daß es (abgesehen von wüsten Casting Hacks in C++, Ada erlaubt das gar nicht) keine Möglichkeit gibt den falschen Typ zu verwenden, weil dies schon beim Übersetzen auffällt. Man hat also einen Fehler schon zu einem sehr frühen Zeitpunkt entdeckt. Die Philosophie dahinter ist, daß man immer nur dann dynamische Elemente der Sprache verwendet, wenn man dies durch das Design unbedingt tun muß und keine andere Möglichkeit hat, ohne das OO Paradigma aufzugeben.

    Es ist der Unterschied zwischen einer Multiparadigmensprache und einer Sprache, die nur ein Paradima unterstützt. Smalltalk (das ist vom Ansatz total sauber und enthält keine C Altlasten wie Objective-C) ist eine reine OOP-Sprache. Die Sprache ist deutlich einfacher als Ada, C++ oder Java, dafür müssen fast alle Prüfungen während der Laufzeit erfolgen. Daher wurde das Unittesting im Smalltalk Umfeld vorangetrieben, weil man andernfalls nur schwer Fehler findet.

    Ada und C++ dagegen sind sehr viel umfangreicher, und somit ist es schwieriger die Sprachen zu erlernen. Dafür kann man deutlich mehr Fehler während der Übersetzungsphase bzw. schon vorher bei einer formalen Prüfung des Programms finden. Immer unter der Prämisse, daß man die Programme entsprechend entwirft.

    Original von Lucas de Vil
    Klar, der Compiler meckert nicht und man sucht sich blöd nach dem Fehler.

    Und das ist der entscheidende Unterschied. Dazu kommt, daß der erzeugte Programmcode schneller ist, aber das ist nur ein Nebeneffekt.