Initialisierung und Variablen Deklaration



  • @john-0 sagte in Initialisierung und Variablen Deklaration:

    C++ ist nicht statisch typisiert, da man zur Laufzeit polymorphen Variablen neue Typen zuweisen kann.

    Ja nee.



  • @Swordfish sagte in Initialisierung und Variablen Deklaration:

    Ja nee.

    Und der dynamic_cast ist eine bloße Einbildung?



  • struct foobar {};
    struct foo : foobar {};
    struct bar : foobar {};
    
    // ...
    
    foobar *f = new foobar;
    f = new foo;
    f = new bar;
    

    Welchen Typ hat f?



  • f ist vom typ zeiger auf foobar und daher sollte man über f nicht auf die (zusätzlichen) methoden der klassen foo und bar zugreifen können?

    der sinn von templates besteht soweit ich weiß darin, dass man eine funktion für alle datentypen hat. soll die funktion also z.b. noch "hello world!" ausgeben, so müsste man bei der verwendung von templates genau eine funktion ändern. hat man dagegen jeweils eine funktion für unsigned char, char, unsigned short int, short int, unsigned int, int, unsigned long int, long int, unsigned long long int, long long int, float, double, long double und jede erdenkliche datenstruktur, klasse usw. so wäre eine so kleine änderung verdammt aufwändig, und aus genau dem grund hat man templates eingeführt.😀



  • @Wade1234 sagte in Initialisierung und Variablen Deklaration:

    f ist vom typ zeiger auf foobar

    Ah. Ok. Danke.



  • Das letzte mal, als ich nachgesehen habe, musste man auch dem dynamic cast sagen, was für ein Typ hinten bei rauskommt.
    Auch wenn der dynamic_cast auf RTTI basiert, ist C++ eine typische statisch typisierte Sprache. Und zwar eine "manifested typed language" (ich komm grade nicht auf den deutschen Begriff).



  • @Schlangenmensch sagte in Initialisierung und Variablen Deklaration:

    ist C++ eine typische statisch typisierte Sprache.

    Danke, ich dachte immer C++ hätte ein dynamisches Typsystem.



  • @Schlangenmensch Ja, ich denke dass C++ statisch typisiert ist ist so ziemlich fast allen klar. Es gibt aber ein paar olle Störsender die hin und wieder nicht anders können als Dinge mit Gewalt miszuverstehen damit sie dagegenreden können. Vielleicht damit sie sich in dem Bewusstsein sonnen können wieder mal Recht gehabt zu haben. Vielleicht ist es auch was persönliches und sie suchen nur bei Benutzern die sie nicht mögen nach Dingen die man irgendwie so hinbiegen könnte dass sie falsch erscheinen. Vielleicht läuft das auch ganz unbewusst. Mir im Prinzip Wurst, denn gottseidank muss ich diese Ergüsse nicht mehr lesen (ausser sie werden von jmd. anderem zitiert wie in diesem Fall).

    Wenn etwas vage oder misverständlich formuliert ist hab ich ja nichts dagegen wenn man darauf hinweist/es verbessert bzw. korrigiert. War aber hier nicht der Fall.



  • @hustbaer sagte in Initialisierung und Variablen Deklaration:

    @Schlangenmensch Ja, ich denke dass C++ statisch typisiert ist ist so ziemlich fast allen klar.

    Die Sache ist ganz einfach, eine statische Typisierung liegt vor, wenn die Typprüfung zum Übersetzungszeitpunkt erfolgt. Simple Frage: Wann wird der Typ in einem dynamic_cast überprüft – beim Übersetzen des Programms oder während der Laufzeit?

    Im Embedded Bereich wird genau aus diesem Grund oftmals C++ ohne RTTI genutzt, diese Untermenge ist dann statisch typisiert. Was ist daran so schwer zu verstehen? Historisch hast Du Recht, aber wir reden da über sehr altes C++ ohne RTTI. Nur irgend wie hält sich so vieles in den Köpfen was schon lange nicht mehr zutreffend ist.



  • @Swordfish sagte in Initialisierung und Variablen Deklaration:

    Welchen Typ hat f?

    Die entscheidende Frage ist nicht welcher Typ hat f, sondern welcher Typ hat *f.



  • @john-0 Du kannst natürlich die Eigenschaft "statically typed" solange verdrehen bis sie in Dein Konzept passt. Just go on. Heck, mit Deiner Herangehensweise ist nichtmal C statically typed.

    Darfst mit Herb weiterstreiten:

    [...] it has static typing but not necessarily "strong" typing.



  • @Swordfish sagte in Initialisierung und Variablen Deklaration:

    @john-0 Du kannst natürlich die Eigenschaft "statically typed" solange verdrehen bis sie in Dein Konzept passt.

    Es ist eine anerkannte Definition in der Informatik. Nur bei einigen Größen der C++ Programmierung will man davon nichts wissen. Fakt ist, bei C++ werden Typprüfungen zur Laufzeit vorgenommen, und zwar immer dann, wenn der dynamic_cast genutzt wird. Wenn Du diese Definition unzutreffend findest, welche Definition benutzt Du? Wie beschreibst Du statische Typisierung und wie verträgt sich damit dynamic_cast?

    Just go on. Heck, mit Deiner Herangehensweise ist nichtmal C statically typed.

    C hat keinerlei Sprachelemente, die es zur Laufzeit erlauben würden eine Typprüfung vorzunehmen. Deshalb C ist komplett statisch typisiert. Allerdings werden in diversen Projekten OOP und somit dynamische Typprüfung in C nach programmiert. Nur wie gesagt, ohne jede Unterstützung durch die Programmiersprache selbst.



  • @john-0 sagte in Initialisierung und Variablen Deklaration:

    Wenn Du diese Definition unzutreffend findest, welche Definition benutzt Du? Wie beschreibst Du statische Typisierung und wie verträgt sich damit dynamic_cast?

    T foo;
    

    foo ist vom Typ T. Und foo wird auch immer vom Typ T bleiben.



  • @Swordfish sagte in Initialisierung und Variablen Deklaration:

    foo ist vom Typ T. Und foo wird auch immer vom Typ T bleiben.

    Damit hast Du gerade CLOS zu einer statisch typisierten Sprache gemacht.

    Nachtrag: Du würdest somit nur Sprachen als dynamisch typisiert klassifizieren, die es erlauben zur Laufzeit bestehende Typen zu verändern z.B. JavaScript. Für das klassische Paradigma der dynamisch typisierten Programmiersprachen SmallTalk trifft das nämlich nicht zu. Ok, Du kannst natürlich darüber argumentieren, dass man in die Variable foo andere Objekte speichern kann, aber exakt das gleiche ist in C++ für Basiszeiger gegeben.



  • @john-0 sagte in Initialisierung und Variablen Deklaration:

    Damit hast Du gerade CLOS zu einer statisch typisierten Sprache gemacht.

    Ich habe garnicht gewusst daß das gültiges Lisp ist.



  • ist es bei templates nicht die aufgabe des compilers, irgendwie zu ermitteln, welcher datentyp da jetzt verwendet wird? das ändert doch nichts daran, dass der assembler dann mov rax, addw etc. übergeben bekommt und der datentyp feststeht, oder doch?
    also "der datentyp" ist ja sowieso schon mal etwas, das nachher im programm nicht mehr existiert.🙄



  • Wenn ich verstanden habe was du meinst nein. Ein template ist ein Platzhalter für den typ einer Funktion oder variablen bei der Verwendung von auto finde der Compiler den Typ automatisch



  • also ich hab jetzt nicht die mega-ahnung von compilerbau, aber ich vermute jetzt mal, dass bei dem programm

    
    template <typename T>
    void swap(T &a, T &b)
    {
    //swappen halt
    }
    
    int main()
    {
         double da, db;
         unsigned int uia, uib;
    
         /*
         irgendwelche initialisierungen
         */
    
         swap(da, db);
         swap(uia, uib);
    
         /*
         weitere swap-aufrufe, änderungen der werte, k.a.
         */
    
         return 0;
    }
    

    zwei versionen von swap erstellt werden: eine für den datentyp double und eine für den datentyp unsigned int. da aber nur eine version von swap im quelltext auftaucht, müsste ja theoretisch der compiler ermitteln, welcher datentyp an swap übergeben wird und dann die entsprechende swap-funktion aufrufen.


  • Mod

    Genau so ist es. Der Compiler weiß ja schließlich, was für einen Typ die Variablen haben, daher kann er das machen. Und das ist auch der Grund, wieso die Templatedefinition immer vorliegen muss, wenn man das Template instanziiert. Der Compiler kann keinen Platzhaltercode erzeugen, der für alle Datentypen passt.

    (Es gibt da natürlich diese eine Variante dieses einen Compilers, wo tatsächlich generischer Platzhaltercode erzeugt wird. Da hat ein Typ jahrelang dran geschrieben, bloß um zu zeigen, dass das berüchtigte extern template aus dem C++98-Standard, an dem sich alle anderen Compilerbauer vergeblich versucht haben, doch möglich ist)



  • @Abe Ein Template ist kein Platzhalter sondern wie der Name schon sagt eine Vorlage. Die Vorlage verwendet dann Platzhalter, die sog. Template-Parameter. Und an vielen Stellen passiert schon genau das was @Wade1234 geschrieben hat, nämlich dass der Compiler anhand von genau definierten Regeln automatisch ermittelt was für die Platzhalter eingesetzt werden soll.

    Beim Beispiel von @Wade1234 oben heisst das Template swap und hat einen Platzhalter namens T. Bei der ersten Verwendung von swap ermittelt der Compiler dann dass double für den Platzhalter T eingesetzt werden muss und bei der zweiten ist es dann unsigned int.

    Nun vergleich das mit:

    template <typename T>
    void swap(T &a, T &b)
    {
    }
    
    int main()
    {
        double da, db;
        unsigned int uia, uib;
    
        // Automatische Ermittlung des Typs direkt über die Verwendung eines Funktions-Tempaltes
        swap(da, db);   // -> swap<double>(double&, double&)
        swap(uia, uib); //  -> swap<unsigned int>(unsigned int&, unsigned int&)
    
        // Automatische Ermittlung des Typs mit auto
        auto daCopy = da;   //  -> double
        swap<decltype(daCopy)>(daCopy, db);    //  -> swap<double>(double&, double&)
        auto uiaCopy = uia; //  -> unsigned int
        swap<decltype(uiaCopy)>(uiaCopy, uib); //  -> swap<unsigned int>(unsigned int&, unsigned int&)
    
         // ...
    }
    

    Der Sinn der 2. Variante ist nur zur Verdeutlichung wie sich auto und Template Argument Deduction ähneln, schreiben würde man das so natürlich nicht.


Anmelden zum Antworten