native oder moderated für den windowseinstieg besser?



  • Also soll ich nachdem ich die Grundlagen beherrsche die Windowsprogrammierung mit MFC anfangen oder? :PP

    Mir genügt ja ein einfaches, nicht höchst-komplexes user-interface für den Anfang. Wie gesagt möchte ich das als Hobby machen und mich vorläufig noch nicht in die tiefsten Tiefen der Sprache einarbeiten, ohne zuvor wenigstens einfache Windowsprogramme schreiben zu können.

    Danke für die Mühe

    @hustebaer :=)
    ist schon verständlich :p. Aber ich als Anfänger weiss es eben noch nicht besser :/.



  • Hier findest du eine Übersicht über GUI-Bibliotheken in C++.

    Zum Beispiel ist VCF relativ unbekannt, aber benutzt verhältnismässig modernes C++ und native Widgets. Modern meine ich z.B. im Vergleich zu wxWidgets. 😉

    <a href= schrieb:

    wxWidgets Style-Guide">1. Don't use C++ templates
    2. Don't use C++ exceptions
    3. Don't use RTTI
    4. Don't use namespaces
    5. Don't use STL
    6. Don't declare variables inside for()
    [...]
    (kurz: Use C with classes :p)



  • Nexus schrieb:

    Hier findest du eine Übersicht über GUI-Bibliotheken in C++.

    Zum Beispiel ist VCF relativ unbekannt, aber benutzt verhältnismässig modernes C++ und native Widgets. Modern meine ich z.B. im Vergleich zu wxWidgets. 😉

    <a href= schrieb:

    wxWidgets Style-Guide">1. Don't use C++ templates
    2. Don't use C++ exceptions
    3. Don't use RTTI
    4. Don't use namespaces
    5. Don't use STL
    6. Don't declare variables inside for()
    [...]
    (kurz: Use C with classes :p)

    Was davon brauchst du für modernes C++ und warum?



  • woooh schrieb:

    Was davon brauchst du für modernes C++ und warum?

    Namespaces um den Code anderer leute nicht mit Bezeichnern zu überfluten, die mit ihrem Code kollidieren? Nur so als Beispiel.



  • otze schrieb:

    woooh schrieb:

    Was davon brauchst du für modernes C++ und warum?

    Namespaces um den Code anderer leute nicht mit Bezeichnern zu überfluten, die mit ihrem Code kollidieren? Nur so als Beispiel.

    Wenn die vor alles wx schreiben dürfte es kaum mit anderen kollidieren. Und vom C with classes zum modernen C++ wird es ja wohl noch nicht weil man alles ein nen Namespace steckt.



  • [quote="woooh"Wenn die vor alles wx schreiben dürfte es kaum mit anderen kollidieren. Und vom C with classes zum modernen C++ wird es ja wohl noch nicht weil man alles ein nen Namespace steckt.[/quote]

    Kürzel für Unterscheidnungen von Klassen verschiedener Bibliothekten zu nehmen, sehe ich als unschön an. Zumal nichts dagegen spricht 2 wx-Bibliothekten irgendwann zu "vereinen". Und dann kannst du wieder Namenskonflikte haben.

    1. Don't use C++ templates
    

    Für bestimmte Mechanismen sind C++ Templates das mittel der Wahl (Policy Based Design etc.). Zudem ist Typsicherheit von Templates sicherlich den Alternativen (Entweder eigene Konstukte für jeden Datentyp, void*...) vorzuziehen.

    2. Don't use C++ exceptions
    3. Don't use RTTI
    

    Beides durchaus gängige und sinnvolle C++ Konstrukte (gerade auch in Kombination).

    4. Don't use namespaces
    

    Wie oben gesagt sind Namesräume deutlich besser als Kürzel geeignet.

    5. Don't use STL
    

    Die STL ist Bestandteil des C++ Standards, und das seit 1998. Das Ausschließen selbiger ist ein Armutszeugnis (zumal in der C++ Standardbibliothek und der STL einige sinnvolle Klassen etc. enthalten sind). Warum alles neu erfinden, oder propritär lösen?

    6. Don't declare variables inside for()
    

    Wiederspricht dem Prinzip alles so lokal wie möglich zu deklarieren.

    Hallo, wir schreiben das Jahr 2010. Der C++ Standard ist von 1998, der TR1 von 2003, der nächste Standard wird vermutlich nächstes Jahr verabschiedet, und selbt für den TR2 steht schon einiges auf der Liste. Die verbreiteten Compiler setzen allesamt inzwischen einen Großteil des Standards um (mit kleinen Ausnahmen zwar, aber vieles kann man als Gegeben betrachten, selbst bei Templates).

    wx ist alles andere als Modern.

    Vieles was in modernen C++ üblich ist (Werf unter anderen mal ein Blick in More C++ Idioms) ist in wx ausgeschlossen.



  • Mit geht es nicht darum wofür die Sachen allgemain da sind, sondern warum man die zu modernem C++ braucht? OK, das mit den Variablen in for ist schon sehr komisch, aber was von den oben genanten Punkten brauchst du für RAII, Copy-and-swap, Safe bool usw. Gerade mal templates sind einigermaßen nützlich für smart pointers, container usw.



  • Nexus schrieb:

    <a href= schrieb:

    wxWidgets Style-Guide">1. Don't use C++ templates
    2. Don't use C++ exceptions
    3. Don't use RTTI
    4. Don't use namespaces
    5. Don't use STL
    6. Don't declare variables inside for()
    [...]
    (kurz: Use C with classes :p)

    Irgendwie zum Schmunzeln 🤡

    Don't use C++ templates
    Besides the reasons mentioned above, template usage also makes the program compile much slower (200%-300% is not uncommon) and their support even in the compilers which have had it for a long time is far from perfect (the best example is probably gcc).

    WTF, die Argumentation ist ja echt ein Hammer.



  • wtfler schrieb:

    Irgendwie zum Schmunzeln 🤡

    Don't use C++ templates
    Besides the reasons mentioned above, template usage also makes the program compile much slower (200%-300% is not uncommon) and their support even in the compilers which have had it for a long time is far from perfect (the best example is probably gcc).

    WTF, die Argumentation ist ja echt ein Hammer.

    Ja, ich würde sagen es braucht 1000%-10000% länger, wenn man richtig viel templates wie boost bind und lambda nimmt.



  • woooh schrieb:

    Mit geht es nicht darum wofür die Sachen allgemain da sind, sondern warum man die zu modernem C++ braucht?

    Weil C++ ohne Templates, Exceptions, Namensräume und STL eben nicht C++ ist. Das sind alles wesentliche Bestandteile der Sprache (die Standardbibliothek gehört dazu).

    woooh schrieb:

    aber was von den oben genanten Punkten brauchst du für RAII, Copy-and-swap, Safe bool usw. Gerade mal templates sind einigermaßen nützlich für smart pointers, container usw.

    Um RAII generisch zu behandeln, kommen oft Templates zum Zug (z.B. die von dir angesprochenen Smart-Pointer oder Container). Davon abgesehen kann man auch sonst viele Probleme sehr elegant mit Templates lösen, und Fehler von der Laufzeit auf die Compilezeit verlagern.

    Eine freie, überladene swap() -Funktion ist essentiell für ADL, ein Abstraktionskonzept von Namensräumen, das Präfixe nicht bieten.

    Die Standard Template Library brauche ich andauernd. Gerade die STL ist ein typisches Beispiel, wie modernes C++ aussehen kann: Dank Templates wird eine Entkopplung von Containern und Algorithmen möglich, wobei Iteratoren das Zwischenstück bilden. Zudem abstrahiert man von Low-Level-Mechanismen wie Zeigerarithmetik und manueller Speicherverwaltung.

    Generell kann man sich mit modernen C++-Errungenschaften von fehleranfälligen Altlasten aus C abwenden. Auch Makros mit ihren Problemen werden oft durch typsichere Alternativen ersetzt.

    wtfler schrieb:

    WTF, die Argumentation ist ja echt ein Hammer.

    Ihre Begründungen sind teilweise wirklich nicht ganz aktuell, hier zum Verzicht auf Exceptions:

    Another reasons not to use it, besides portability, are the performance penalty it imposes (small, but, at least for current compilers, non-zero), and subtle problems with memory/resource deallocation it may create (the place where you'd like to use C++ exceptions most of all are the constructors, but you need to be very careful in order to be able to do it).

    Performance ist im Fehlerfall in der Regel nicht entscheidend, und Exceptionsicherheit wird damit natürlich ein Thema (das mit RAII aber gut zu bewältigen ist).

    Das soll nicht heissen, dass wxWidgets schlecht ist. Es ist mit Sicherheit ein sehr mächtiges Framework, und für GUI gerade eines der wenigen, das native Widgets unterstützt. Aber es ist seiner Zeit eben etwas hinterher. Im Jahr 2010 stimmt es einfach nicht mehr, dass die erwähnten Sprachmittel kaum von Compilern unterstützt werden.

    stimmt schrieb:

    Ja, ich würde sagen es braucht 1000%-10000% länger, wenn man richtig viel templates wie boost bind und lambda nimmt.

    Bind geht noch, aber Lambda verwende ich z.B. auch nicht. Man muss ja auch nicht die Hardcore-Boost-Möglichkeiten nutzen, die quasi neue Sprachmittel emulieren. Aber bereits von Makros zu Templates für generische Container ist ein grosser Schritt.



  • Nexus schrieb:

    woooh schrieb:

    aber was von den oben genanten Punkten brauchst du für RAII, Copy-and-swap, Safe bool usw. Gerade mal templates sind einigermaßen nützlich für smart pointers, container usw.

    Um RAII generisch zu behandeln, kommen oft Templates zum Zug (z.B. die von dir angesprochenen Smart-Pointer oder Container). Davon abgesehen kann man auch sonst viele Probleme sehr elegant mit Templates lösen, und Fehler von der Laufzeit auf die Compilezeit verlagern.

    Eine freie, überladene swap() -Funktion ist essentiell für ADL, ein Abstraktionskonzept von Namensräumen, das Präfixe nicht bieten.

    Die Standard Template Library brauche ich andauernd. Gerade die STL ist ein typisches Beispiel, wie modernes C++ aussehen kann: Dank Templates wird eine Entkopplung von Containern und Algorithmen möglich, wobei Iteratoren das Zwischenstück bilden. Zudem abstrahiert man von Low-Level-Mechanismen wie Zeigerarithmetik und manueller Speicherverwaltung.

    Generell kann man sich mit modernen C++-Errungenschaften von fehleranfälligen Altlasten aus C abwenden. Auch Makros mit ihren Problemen werden oft durch typsichere Alternativen ersetzt.

    Natürlich kann man nicht alles machen, wenn man nicht alles verwendet. Man kann statt mit Generizität vieles auch mit Objektorientierung machen, das ist dann mehr Java oder C# Style, aber von C with classes ist man immer noch weit entfernt. Ich hab das wxWidgets Zeugs noch nie verwendet und es kann sein, dass das C with classes ist.

    Nexus schrieb:

    Exceptionsicherheit wird damit natürlich ein Thema (das mit RAII aber gut zu bewältigen ist).

    Nö da musst du schon mehr aufwand reinstecken, der Destruktor wird garnicht aufgerufen, wenn im Konstruktor eine Exception fliegt.



  • woooh schrieb:

    Man kann statt mit Generizität vieles auch mit Objektorientierung machen, das ist dann mehr Java oder C# Style

    Das ist in C++ nicht ganz so einfach, weil z.B. nicht alle Typen von Object erben und nicht wenige Typen gar keine Klassen sind.

    Wie würdest du std::vector mit dynamischer Polymorphie implementieren, damit man sowohl int als auch eine eigene Klasse MyClass verwenden könnte? Du müsstest auf Typsicherheit verzichten, wie man es in Java vor den Generics getan hat. Du könntest nur Klassen verwenden, die von einer bestimmten Basisklasse abgeleitet sind.

    Wenn man wie wxWidgets Makros für Container verwendet, ist man teilweise sogar flexibler als mit Laufzeitpolymorphie. Weil eben die Typen zur Kompilierzeit bereits feststehen. Dafür hat man andere Nachteile.

    woooh schrieb:

    Nexus schrieb:

    Exceptionsicherheit wird damit natürlich ein Thema (das mit RAII aber gut zu bewältigen ist).

    Nö da musst du schon mehr aufwand reinstecken, der Destruktor wird garnicht aufgerufen, wenn im Konstruktor eine Exception fliegt.

    Nein, musst du nicht. Wieso sollte der Destruktor aufgerufen werden, wenn das Objekt noch nicht fertig konstruiert ist?

    struct MyClass
    {
        A* a;
        B* b;
    
        MyClass() : a(new A), b(new B)
        {
            // wenn der B-Konstruktor wirft, sind wir verloren.
        }
    };
    

    Mit RAII:

    struct MyClass
    {
        scoped_ptr<A> a;
        scoped_ptr<B> b;
    
        MyClass() : a(new A), b(new B)
        {
            // Problem gelöst
        }
    };
    

    Ohne Exceptions hat man im Konstruktor vor allem auch das Problem von anderen Ressourcenanforderungen, da man dem Aufrufer keinen Fehler mitteilen kann. Man müsste entweder in der Klasse ein Valid-Flag mitführen (unschön) oder nachträgliche Init-Funktionen bereitstellen (unschön).



  • Nexus schrieb:

    woooh schrieb:

    Nexus schrieb:

    Exceptionsicherheit wird damit natürlich ein Thema (das mit RAII aber gut zu bewältigen ist).

    Nö da musst du schon mehr aufwand reinstecken, der Destruktor wird garnicht aufgerufen, wenn im Konstruktor eine Exception fliegt.

    Nein, musst du nicht. Wieso sollte der Destruktor aufgerufen werden, wenn das Objekt noch nicht fertig konstruiert ist?

    struct MyClass
    {
        A* a;
        B* b;
    
        MyClass() : a(new A), b(new B)
        {
            // wenn der B-Konstruktor wirft, sind wir verloren.
        }
    };
    

    Mit RAII:

    struct MyClass
    {
        scoped_ptr<A> a;
        scoped_ptr<B> b;
    
        MyClass() : a(new A), b(new B)
        {
            // Problem gelöst
        }
    };
    

    Ohne Exceptions hat man im Konstruktor vor allem auch das Problem von anderen Ressourcenanforderungen, da man dem Aufrufer keinen Fehler mitteilen kann. Man müsste entweder in der Klasse ein Valid-Flag mitführen (unschön) oder nachträgliche Init-Funktionen bereitstellen (unschön).

    Schau dir mal die std::fstreams an, die werfen erst mal keine Exception. Exceptionsicherheit bei Zuweisungen gibts auch noch, das ist nicht nur RAII.



  • woooh schrieb:

    Schau dir mal die std::fstreams an, die werfen erst mal keine Exception.

    Die C++-Streams ermöglichen dem Benutzer, beide Wege zu gehen (und werden dafür auch teilweise kritisiert). Mit der exceptions() -Methode kann man Exceptions einschalten.

    woooh schrieb:

    Exceptionsicherheit bei Zuweisungen gibts auch noch, das ist nicht nur RAII.

    Natürlich ist Exceptionsicherheit nicht nur RAII. Aber RAII trägt enorm zur Umsetzung von Exceptionsicherheit (und generell zur Kapselung von fehleranfälligen oder Low-Level-Konstrukten) bei. Ohne RAII hast du oft hässliche If-Else- oder Try-Catch-Abfragen, die den Code sehr unübersichtlich machen. Alleine schon beim vorherigen Beispiel für 2 Variablen. Jede weitere würde den Code noch komplexer schachteln.

    MyClass()
    {
        a = new A;
        try
        {
            b = new B;
        }
        catch (...)
        {
            delete a;
            throw;
        }
    };
    


  • Nexus schrieb:

    woooh schrieb:

    Schau dir mal die std::fstreams an, die werfen erst mal keine Exception.

    Die C++-Streams ermöglichen dem Benutzer, beide Wege zu gehen (und werden dafür auch teilweise kritisiert). Mit der exceptions() -Methode kann man Exceptions einschalten.

    darum sag ich ja "erst mal"

    woooh schrieb:

    Exceptionsicherheit bei Zuweisungen gibts auch noch, das ist nicht nur RAII.

    Natürlich ist Exceptionsicherheit nicht nur RAII. Aber RAII trägt enorm zur Umsetzung von Exceptionsicherheit (und generell zur Kapselung von fehleranfälligen oder Low-Level-Konstrukten) bei. Ohne RAII hast du oft hässliche If-Else- oder Try-Catch-Abfragen, die den Code sehr unübersichtlich machen. Alleine schon beim vorherigen Beispiel für 2 Variablen. Jede weitere würde den Code noch komplexer schachteln.

    MyClass()
    {
        a = new A;
        try
        {
            b = new B;
        }
        catch (...)
        {
            delete a;
            throw;
        }
    };
    

    Hat auch keiner behauptet das man RAII nicht nehmen soll, sondern nur das es nicht reicht.


Anmelden zum Antworten