Typ casten?



  • class a{
    public:
      int x;
      bool y;
    };
    
    class b : public a{
    public:
     int getX(){return x;}
    };
    
    class c : public a{
    public:
     bool getY(){return y;}
    };
    
    int main(){
     a test();
    
     static_cast<b>(test).getX();
     reinterpret_cast<c>(test).getY();
    
     return 0;
    }
    

    Geht das iwie 😕



  • Dynamic cast



  • 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.


Anmelden zum Antworten