Typ casten?



  • fufhd schrieb:

    Dynamic cast

    ./ast/ast_value.h:225:21: error: 'ipv_c' is not polymorphic
                    return ipv_int_c((dynamic_cast<ipv_int_c*>(&left))->toInt() + ((ipvt_int_c)right).toInt());
    

    Ich werd mit C++ einfach nicht warm 😞



  • Du kannst aus einem a selbstverständlich kein b oder c machen. Mal davon abgesehen sollte dein test eine Funktionsdeklaration sein.



  • junta schrieb:

    Ich werd mit C++ einfach nicht warm 😞

    Das liegt nicht an C++ sondern daran, dass du Vererbung/Polymorphie nicht verstanden hast.

    Angenommen die Klasse a steht für Tier und die Klasse b steht für Katze. Du versuchst nun aus einem Tier eine Katze zu machen. Aber nicht jedes Tier ist eine Katze 😉

    Schau dir noch einmal genau an was Vererbung macht. Stickwort "is-a relationship".



  • a test();
    

    ist eine Funktionsdeklaration, richtig wäre

    a test;
    

    Aber wie gesagt kannst du ein a -Objekt (das tatsächlich als a konstruiert wurde), nicht zu einem b oder c konvertieren. Davon abgesehen führt man Downcasts auf Zeiger oder Referenzen durch...



  • Nexus schrieb:

    a test();
    

    ist eine Funktionsdeklaration

    Nexus schrieb:

    a test();
    

    ist eine Funktionsdeklaration

    Und ich dachte da wird dann direkt der Konstruktor aufgerufen 😕

    icarus2 schrieb:

    Das liegt nicht an C++ sondern daran, dass du Vererbung/Polymorphie nicht verstanden hast.

    Doch, schon. In anderen Sprachen funktioniert das ja auch. Sogar in C...



  • junta schrieb:

    icarus2 schrieb:

    Das liegt nicht an C++ sondern daran, dass du Vererbung/Polymorphie nicht verstanden hast.

    Doch, schon. In anderen Sprachen funktioniert das ja auch. Sogar in C...

    Nein, tut es nicht. Erst recht nicht in C!



  • Nathan schrieb:

    junta schrieb:

    icarus2 schrieb:

    Das liegt nicht an C++ sondern daran, dass du Vererbung/Polymorphie nicht verstanden hast.

    Doch, schon. In anderen Sprachen funktioniert das ja auch. Sogar in C...

    Nein, tut es nicht. Erst recht nicht in C!

    Wie auch immer. Wenn es mal läuft und mich C++ dann noch immer abfuckt, portiere ich es zu C!



  • junta schrieb:

    Nathan schrieb:

    junta schrieb:

    icarus2 schrieb:

    Das liegt nicht an C++ sondern daran, dass du Vererbung/Polymorphie nicht verstanden hast.

    Doch, schon. In anderen Sprachen funktioniert das ja auch. Sogar in C...

    Nein, tut es nicht. Erst recht nicht in C!

    Wie auch immer. Wenn es mal läuft und mich C++ dann noch immer abfuckt, portiere ich es zu C!

    Wo C ja auch soviel einfacher und anwenderfreundlicher als C++ ist...



  • junta schrieb:

    Doch, schon. In anderen Sprachen funktioniert das ja auch. Sogar in C...

    Das "funktioniert" in keiner Sprache, weil es einfach keinen Sinn macht.
    Wenn du ein a nach b castest und b noch zusätzliche Member hätte, wo sollen dann deren Werte herkommen? Soll sich der Compiler welche ausdenken?

    Du kannst einen Zeiger oder eine Referenz auf a nach b mithilfe von dynamic_cast nach b casten, wenn - und nur wenn - es sich in Wirklichkeit um eine Instanz von b (oder einer abgeleiteten Klasse von b) handelt.



  • Nathan schrieb:

    junta schrieb:

    Nathan schrieb:

    junta schrieb:

    icarus2 schrieb:

    Das liegt nicht an C++ sondern daran, dass du Vererbung/Polymorphie nicht verstanden hast.

    Doch, schon. In anderen Sprachen funktioniert das ja auch. Sogar in C...

    Nein, tut es nicht. Erst recht nicht in C!

    Wie auch immer. Wenn es mal läuft und mich C++ dann noch immer abfuckt, portiere ich es zu C!

    Wo C ja auch soviel einfacher und anwenderfreundlicher als C++ ist...

    Wenn man nicht Jahre Zeit hat richtiges C++ zu lernen ist es besser sich C in wenigen Wochen komplett anzueignen und dann los zulegen. Tut mal alle nicht so als wenn man in C keine geile kleine Software schreiben kann. Nicht jeder arbeitet im Team an großen Projekten.



  • junta schrieb:

    icarus2 schrieb:

    Das liegt nicht an C++ sondern daran, dass du Vererbung/Polymorphie nicht verstanden hast.

    Doch, schon. In anderen Sprachen funktioniert das ja auch. Sogar in C...

    Nein, es klappt nicht! Du kannst das in C++, Java, C#, Eiffel oder was auch immer versuchen. Es klappt nicht weil es konzeptuell falsch ist.

    Aber zeig mal wie du das in C hinbekommst 😉



  • EinfachC schrieb:

    Nathan schrieb:

    junta schrieb:

    Nathan schrieb:

    junta schrieb:

    icarus2 schrieb:

    Das liegt nicht an C++ sondern daran, dass du Vererbung/Polymorphie nicht verstanden hast.

    Doch, schon. In anderen Sprachen funktioniert das ja auch. Sogar in C...

    Nein, tut es nicht. Erst recht nicht in C!

    Wie auch immer. Wenn es mal läuft und mich C++ dann noch immer abfuckt, portiere ich es zu C!

    Wo C ja auch soviel einfacher und anwenderfreundlicher als C++ ist...

    Wenn man nicht Jahre Zeit hat richtiges C++ zu lernen ist es besser sich C in wenigen Wochen komplett anzueignen und dann los zulegen. Tut mal alle nicht so als wenn man in C keine geile kleine Software schreiben kann. Nicht jeder arbeitet im Team an großen Projekten.

    Ja, das mag ja sein.
    Ich selber komme von C. Und dieses Char-Array-Pointer-String-Gefrickel ist echt nicht schön. C++ ist bei soetwas wesentlich anwenderfreundlicher.
    Aber ich wollte hier jetzt keine Diskussion lostreten.



  • Nathan schrieb:

    Wo C ja auch soviel einfacher und anwenderfreundlicher als C++ ist...

    Ich dachte bis jetzt nicht, dass es irgendwie strittig sei, dass C bedeutend einfacher als C++ ist. C++ ist (absolut und relativ zu C gesehen) einfach saumäßig komplex. Die Frage, ob diese Komplexität nötig oder zumindest gerechtfertigt ist, lasse ich hier mal bewusst außen vor.

    "Anwenderfreundlich" ist wohl Ansichtssache. Der Anwender ist hier schließlich ein Programmierer, der, wenn er was auf sich hält, exakt verstehen muss, was sein Code macht. Ist man erstmal so weit, dass man die C++-Sprachkonzepte und die Standardlibrary soweit verinnerlicht hat, mag C++ definitiv bequemer zu nutzen sein. Der zu erbringende Aufwand ist aber nicht zu unterschätzen. C hingegen kann ein guter Programmierer deutlich schneller soweit beherrschen, dass ich seinen Code auf meine kritischen Server lassen würde.

    Ich habe kein gutes Gefühl dabei, wenn Programmierer Librarycode nutzen, den sie nicht auch selbst implementieren könnten, wenn es denn nötig wäre. Tatsächlich machen sollen sie das selbstverständlich nicht, aber sie sollten definitiv dazu in der Lage sein.



  • etext schrieb:

    Ich dachte bis jetzt nicht, dass es irgendwie strittig sei, dass C bedeutend einfacher als C++ ist.

    Doch. C ist leichter zu lernen, aber ganz sicher nicht einfacher zu benutzen.
    Assembler ist noch viel leichter als C zu lernen, aber niemand käme auf die Idee, Assembler als einfacher als C darzustellen.



  • Man sollte einfach und leicht auseinanderhalten.



  • ifsw schrieb:

    Das "funktioniert" in keiner Sprache, weil es einfach keinen Sinn macht.
    Wenn du ein a nach b castest und b noch zusätzliche Member hätte, wo sollen dann deren Werte herkommen? Soll sich der Compiler welche ausdenken?

    Der Punkt ist, dass ich weiß, dass die Klassen bis auf die Methoden identisch sind 😉



  • Aus welchem Grund hast du dann überhaupt mehrere Klassen? Lass halt die Vererbung sein und pack die Methoden in die Basisklasse (oder schreib freie Funktionen). Es scheint ja nicht so zu sein, dass du hier irgendwas voneinander trennen wolltest -- sonst würde sich die Frage nach dem Cast gar nicht erst stellen.

    Wenn du dir unbedingt in den Fuß schießen willst, durch den Compiler kriegst du das beispielsweise so:

    a foo;
    static_cast<b*>(static_cast<void*>(&foo))->getX();
    

    bzw. allgemein formuliert:

    #include <iostream>
    #include <type_traits>
    
    template<typename T, typename U>
    T stupid_cast(U &&obj) {
      return *static_cast<typename std::remove_reference<T>::type *>(static_cast<void*>(const_cast<typename std::remove_cv<typename std::remove_reference<U>::type>::type *>(&obj)));
    }
    
    struct A {
      int x;
    };
    
    struct B : A {
      int getX() { return x; }
    };
    
    int main() {
      A a { 10 };
      std::cout << stupid_cast<B&>( a) .getX() << '\n';
      std::cout << stupid_cast<B*>(&a)->getX() << '\n';
    }
    

    Aber komm nicht heulend her, sobald (nicht falls) dir das explodiert. Du wurdest ausgiebig gewarnt.



  • ifsw schrieb:

    etext schrieb:

    Ich dachte bis jetzt nicht, dass es irgendwie strittig sei, dass C bedeutend einfacher als C++ ist.

    Doch. C ist leichter zu lernen, aber ganz sicher nicht einfacher zu benutzen.
    Assembler ist noch viel leichter als C zu lernen, aber niemand käme auf die Idee, Assembler als einfacher als C darzustellen.

    Ich habe als Bub damals mit Assembler angefangen und fand es dementsprechend total einfach, weil man hier bei jedem Befehl genau weiß was er macht. Bei C ist man schon auf den Compiler angewiesen, aber C kann noch sehr gut optimiert werden. C++ hingegen hat schon wieder viele Automatismen eingebaut und wenn es nicht extrem gut beherrscht wird mit Sicherheit kein besseres Programm als bei C damit raus kommen.

    Wem Pointer und manuelle Speicherverwaltung schon zu schwer sind, der sollte um C++ einen weiten Bogen machen. Hier alles richtig zu machen erfordert sehr viele Jahre Erfahrung. Wie schon der Erfinder von C++ sagte: "In C kann man sich in den Fuß schießen, macht man bei C++ was falsch ist das ganze Bein weg"

    Das Risiko mit C++ Murks zu programmieren ist daher jedenfalls am höchsten.



  • ASMdannC schrieb:

    Wie schon der Erfinder von C++ sagte: "In C kann man sich in den Fuß schießen, macht man bei C++ was falsch ist das ganze Bein weg"

    Das Zitat solltest du nochmal nachlesen. Oder, wenn es dir bekannt ist, aufhören, es sinnentstellend zu benutzen.

    Wie dem auch sei, der Trick, effektives C++ zu schreiben ist (wie bei jeder Hochsprache), die Automatismen für sich einzusetzen. Wer bei RAII bemängelt, dass man in der Funktion nicht sieht, was beim Verlassen selbiger passiert, hat schlicht nicht verstanden, dass der Sinn der Sache ist, sich nicht darum kümmern zu müssen.

    Grundsätzlich: Programmierung besteht in erster Linie nicht daraus, einer Maschine zu erklären, was sie tun soll, sondern daraus, komplexe Probleme zu ordnen und zu formalisieren. Man mag auf die alte Tour kleinere Dinge noch zustandekriegen, aber beispielsweise eine Office-Suite in Assembler zu schreiben (und später zu warten!), ist reiner Wahnsinn. Die Registermaschine ist ab einer gewissen, nicht sonderlich großen Programmgröße nicht die Ebene, auf der man sich gedanklich bewegen will. Stattdessen konstruiert man sich ein Modell, mit dem man als Mensch umgehen kann und das gleichzeitig einer Maschine erklärbar ist, und dafür ist es sehr hilfreich, bestimmte, wiederkehrende Muster, die man häufig in solchen Modellen braucht, der Maschine automatisiert erklären zu lassen. Das fängt bei Funktionsaufrufen an, geht über Vererbung und virtuelle Funktionstabellen bis hin zu Exceptions, um ein paar Beispiele rauszugreifen.

    Jetzt ist es möglich, Vererbung in C abzubilden -- schau dir nur die glib an. Man sieht dann auch sofort, wie das auf der Maschine funktioniert. Trotzdem will man das nicht benutzen müssen, wenn man es vermeiden kann. Es ist möglich, Exceptions in Assembler zu bauen, und man sieht dann auch ganz genau, wie die Mechanismen funktionieren (ob man sich darin zurechtfände, wenn man nicht schon wüsste, wie sie funktionieren, lassen wir mal außen vor). Trotzdem will man das nicht machen müssen, schon weil man die Tables für das Stack-Unwinding von Hand bauen müsste. In der Praxis führt das dazu, dass in Low-Level-Sprachen die Mechanismen, die erst mühselig von Hand gebaut werden müssten und ausgesprochen unbequem zu benutzen sind, nicht benutzt werden, auch wenn sie für die Modellierung des zu lösenden Problems sehr hilfreich wären.

    Also ja: es gibt in C++ (wie in anderen Hochsprachen) Dinge, die man erstmal verstehen muss, bevor man sie effektiv einsetzen kann, und ja, Dinge zu verstehen erfordert Zeit und Mühe. Aber nahezu durch die Bank weg handelt es sich dabei um Dinge, die, wenn man sie verstanden hat, einem das Leben einfacher machen. Und um in der Programmierung einen Fuß auf den Boden zu kriegen, wird der TE sich auf kurz oder lang damit beschäftigen müssen, wie Vererbung funktioniert und wofür es gedacht ist. Allein von der Maschine her zu denken ist nur in Ausnahmefällen sinnvoll.



  • junta schrieb:

    ifsw schrieb:

    Das "funktioniert" in keiner Sprache, weil es einfach keinen Sinn macht.
    Wenn du ein a nach b castest und b noch zusätzliche Member hätte, wo sollen dann deren Werte herkommen? Soll sich der Compiler welche ausdenken?

    Der Punkt ist, dass ich weiß, dass die Klassen bis auf die Methoden identisch sind 😉

    ist junta also der offizielle blurry des c++-forums?


Anmelden zum Antworten