john 0 erklaert C++ casts



  • @It0101 sagte in john 0 erklaert C++ casts:

    Ich habe eigentlich nicht verstanden warum ihr euch hier so in die Haare bekommt.

    Der Herr reagiert sehr dünnhäutig darauf, wenn man seinen Stil zu programmieren kritisiert. Einige hier im Forum hängen einer Ideologie an, dass man keinerlei manuelle Speicherverwaltung machen dürfe. Das führt dann in diesem konkreten Beispiel zu einem zweifelhaften Design. Wann wenn nicht in einem Container sollte man manuelle Speicherverwaltung machen?

    P.S. Wie man es ohne cast hinbekommt, habe ich im original Thread mittlerweile gepostet. Das ist die Minimallösung. Die saubere Lösung wäre die Containerklasse komplett mit eigener Speicherverwaltung zu schreiben, und dann wird auch schnell ersichtlich, weshalb propagate_on_container_swap, propagate_on_container_copy_assigment, propagate_on_container_move_assigment alles andere als Trivialitäten sind.



  • @eigenartig sagte in john 0 erklaert C++ casts:

    C-Style Casts sind viel übersichtlicher

    Sie verdecken Fehler, und das ist ein Problem. Dazu kann man dynamic_cast nicht durch einen C-Cast ersetzen.



  • @john-0 sagte in john 0 erklaert C++ casts:

    Sie verdecken Fehler, und das ist ein Problem.

    C++-Style Casts können auch falsch benutzt werden. Darüber streitet ihr euch doch.

    @john-0 sagte in john 0 erklaert C++ casts:

    Dazu kann man dynamic_cast nicht durch einen C-Cast ersetzen.

    Eine Klasse mittels dynamic_cast<> herauszufinden ist sowieso fragwürdiges Design.



  • @eigenartig sagte in john 0 erklaert C++ casts:

    C++-Style Casts können auch falsch benutzt werden.

    Ja, aber da schrillen bei einem const_cast<> oder einem reinterpret_cast<> sofort die Alarmglocken.

    @eigenartig sagte in john 0 erklaert C++ casts:

    Eine Klasse mittels dynamic_cast<> herauszufinden ist sowieso fragwürdiges Design.

    weil?



  • @john-0 sagte in john 0 erklaert C++ casts:

    Der Herr reagiert sehr dünnhäutig darauf, wenn man seinen Stil zu programmieren kritisiert. Einige hier im Forum hängen einer Ideologie an, dass man keinerlei manuelle Speicherverwaltung machen dürfe. Das führt dann in diesem konkreten Beispiel zu einem zweifelhaften Design. Wann wenn nicht in einem Container sollte man manuelle Speicherverwaltung machen?

    Das sehe ich eigentlich ähnlich wie "einige". Es gibt kaum noch plausible Gründe selber Speicher zu allokieren.



  • @eigenartig sagte in john 0 erklaert C++ casts:

    Eine Klasse mittels dynamic_cast<> herauszufinden ist sowieso fragwürdiges Design.

    Nur mal ein Beispiel warum C-Style-Casts nicht so toll sind:

    class A {};
    class B : public A {};
    class C {};
    
    int main( int argc, char **argv)
    {
        B b;
        // B Kommt als Basisklasse daher, wie es oft ist
        A *a = &b;
    
        // C-Style-Cast
        C *c1 = (C*)a; // Das kompiliert
    
        // C++-Style-Cast
        C *c2 = dynamic_cast<C*> ( a ); // Das kompiliert nicht
    

    D.h. schon der Compiler weist dich bei der C++-Cast-Variante darauf hin, dass hier was nicht stimmt.
    Übrigens mit der Meldung

    "error: cannot dynamic_cast 'a' (of type 'class A*') to type 'class C*' (source type is not polymorphic)|"

    Bei der C-Style-Cast-Variante läufst du ins offene Messer, rufst irgendwann eine Funktion deines Objects "c1" auf und dann machts bumm. Vielleicht nicht sofort. Wenn es eine selten genutzte Funktion ist, in der du castest knallt es vielleicht erst in 10 Wochen, während der verantwortliche Entwickler im Urlaub ist und der ahnungslose Kollege gerade das Hanfseil am Balkon befestigt, weil er die Crash-Ursache in Produktion nicht findet und die Kunden beim Support Sturmklingeln.

    Dann kommt "eigenartig" aus dem Urlaub zurück und sagt: "ja ich fand C-style-Casts viel hübscher. That's my style bitches!".



  • @It0101 sagte in john 0 erklaert C++ casts:

    Das sehe ich eigentlich ähnlich wie "einige". Es gibt kaum noch plausible Gründe selber Speicher zu allokieren.

    „Kaum noch“ heißt aber nicht „keine“ und insbesondere Container (alle Standardcontainer haben optionale Argumente für Allokatoren) sind hier die Ausnahme. Wenn man einen Standardcontainer nachbauen will, bzw. einen Container im Stile der Standardcontainer realisieren will, wird man um die Verwendung von Allokatoren nicht herum kommen. Wenn man Allokatoren nutzt, ist auch das Cast-Problem aus der Welt.



  • @john-0 Warum sollte man einen Standard-Container nachbauen wollen? Gerade die Container sind im Gegensatz zu den Strings oder StreamStreams sogar sehr performant und konnten zumindest meine Bedürfnisse bis jetzt immer erfüllen.



  • @It0101 sagte in john 0 erklaert C++ casts:

    @john-0 Warum sollte man einen Standard-Container nachbauen wollen?

    Genau das war aber das Thema des Threads aus dem mein Posting ausgelagert wurde.

    Ist es sinnvoll? Nein, da wirst Du von mir keinen Widerspruch hören. Es ist sinnvoll einen Container einmal selbst implementiert zu haben – möglicherweise.



  • @john-0 sagte in john 0 erklaert C++ casts:

    @It0101 sagte in john 0 erklaert C++ casts:

    @john-0 Warum sollte man einen Standard-Container nachbauen wollen?

    Genau das war aber das Thema des Threads aus dem mein Posting ausgelagert wurde.

    Ist es sinnvoll? Nein, da wirst Du von mir keinen Widerspruch hören. Es ist sinnvoll einen Container einmal selbst implementiert zu haben – möglicherweise.

    Klar macht das Sinn, wenigstens einmal eine Container-Struktur gebaut zu haben. Nicht unbedingt weil man viel über Iteratoren lernt, sondern weil man was über das saubere Arbeiten mit Speicher, Pointern, Speicherblöcken usw. lernt.

    Das Wissen kann man allerdings auch anderswo aufsammeln. Z.B. wenn man mit Sockets arbeitet und Protokolle entwirft. Aber ich stimme dir zu: Es schadet nicht, es mal gemacht zu haben.



  • @It0101 sagte in john 0 erklaert C++ casts:

    Warum sollte man einen Standard-Container nachbauen wollen?

    Vielleicht, weil man bestimmte Eigenschaften ausnutzen will - z.B. wenn man nur über die Daten weiß, dass man sie relocaten kann und die Werte einfach im Speicher rumgeschoben werden können, ohne Konstruktoren aufrufen zu müssen? So ein Container für PODs ohne interne Pointer zum Beispiel. Da kann man beim resizen z.B. realloc verwenden, wenn man will. Oder auch memcopy anstatt Konstruktoren und Destruktoren aufzurufen. std::vector ist voll generisch und muss all diese Spezialfälle abdecken. Wenn man darauf verzichten kann, kann man u.U. besser sein.



  • @wob sagte in john 0 erklaert C++ casts:

    @It0101 sagte in john 0 erklaert C++ casts:

    Warum sollte man einen Standard-Container nachbauen wollen?

    Wenn man darauf verzichten kann, kann man u.U. besser sein.

    Ja, aber das sind Spezialfälle. Für 99% aller Anwendungenm kommt man mit den STL-Containern. Beim STL-String und beim Stringstream sehe ich da schon eher "Neuimplementations-Fälle".



  • @It0101 sagte in john 0 erklaert C++ casts:

    Dann kommt "eigenartig" aus dem Urlaub zurück und sagt: "ja ich fand C-style-Casts viel hübscher. That's my style bitches!".

    Find ich auch immer noch. Ich schreib halt keine Fehler was das angeht 🙂

    @Swordfish sagte in john 0 erklaert C++ casts:

    weil?

    Code Smell.



  • @eigenartig sagte in john 0 erklaert C++ casts:

    Find ich auch immer noch. Ich schreib halt keine Fehler was das angeht

    🤦🏻♂

    @eigenartig sagte in john 0 erklaert C++ casts:

    Code Smell.

    weil?



  • @Swordfish sagte in john 0 erklaert C++ casts:

    weil?

    Heuristik



  • @It0101 sagte in john 0 erklaert C++ casts:

    @john-0 Warum sollte man einen Standard-Container nachbauen wollen? Gerade die Container sind im Gegensatz zu den Strings oder StreamStreams sogar sehr performant und konnten zumindest meine Bedürfnisse bis jetzt immer erfüllen.

    Ein einfaches Beispiel die std::map hat für die Methode insert oder count O(log(n)) Laufzeit.
    Jetzt brauchst du eine Datenstruktur die es in O(1) count ausführt und O(n) Laufzeit einfügen kann und das im Worst Case.

    Was würdest du dann tun ?



  • @pmqtt sagte in john 0 erklaert C++ casts:

    @It0101 sagte in john 0 erklaert C++ casts:

    @john-0 Warum sollte man einen Standard-Container nachbauen wollen? Gerade die Container sind im Gegensatz zu den Strings oder StreamStreams sogar sehr performant und konnten zumindest meine Bedürfnisse bis jetzt immer erfüllen.

    Ein einfaches Beispiel die std::map hat für die Methode insert oder count O(log(n)) Laufzeit.
    Jetzt brauchst du eine Datenstruktur die es in O(1) count ausführt und O(n) Laufzeit einfügen kann und das im Worst Case.

    Was würdest du dann tun ?

    Ich sag ja nicht, dass man NIE Container selber schreiben sollte. Es gibt Ausnahmen, da macht das Sinn. Ich hatte diese Ausnahme bisher nur seeeehr selten.

    Ich hab mir auch nen Puffer selber gebaut, weil mir eben der STL-String zu langsam war. Ist halt manchmal notwendig.


Anmelden zum Antworten