Initialisierung und Variablen Deklaration



  • Hallo, wie man sieht, ich bin neu hier und hoffe meine Frage richtig zu formulieren. Ich arbeite gerade mit dem Buch von Bjarne Stroustrup und hänge an Seite 299. Sehr wahrscheinlich eine relativ einfache Sache. Aber hier gibt es eine Syntax, die ich prinzipiell nicht verstehe. Für was steht denn das T hier? Viele Grüße und Danke ```cpp

    void f(T x);
    f(y);
    T x=y; // initialisiere x mit y


  • T steht für einen beliebigen Typ ... int, double, char, my_fancy_class_t, ...



  • T steht für einen generischen Typ.
    das T kann also ein int , ein float, ein double etc. sein.
    Generics sind eine schöne Sache, dar das Programm zur Laufzeit den Typ selbst bestimmen kann. Das T wird dann durch den Typ ersetzt , der gerade benutzt werden muss.
    du kannst die Funktion also folgendermaßen aufrufen:

    int x = 10;
    double y = 10;
    float z = 10;
    f(x);
    f(y);
    f(z);
    
    


  • @Swordfish Danke. Für mich wirkt das seltsam aber jetzt einleuchtend. Wieso der Autor nicht einfach dann int, oder double o.ä einsetzt. Aber danke für deine Antwort 🙂



  • @STOERSENDER sagte in Initialisierung und Variablen Deklaration:

    Wieso der Autor nicht einfach dann int, oder double o.ä einsetzt.

    Spätestens wenn Du zu Templates kommst verstehst Du es.



  • @xe-li Ah, so ergibt das für mich nun auch wirklich Sinn.....



  • @STOERSENDER sagte in Initialisierung und Variablen Deklaration:

    Wieso der Autor nicht einfach dann int, oder double o.ä einsetzt.

    Vermutlich weil er zeigen wollte dass es nicht nur für int oder double geht, sondern für beliebige Typen - vorausgesetzt sie haben einen Copy-Konstruktor...
    ...und ihm nicht klar war dass er damit Anfänger verwirren wird die noch nicht wissen dass T sehr oft mit der Bedeutung "ein beliebiger Typ" verwendet wird.
    (Bzw. halt "ein beliebiger Typ der bestimmte Voraussetzungen erfüllt" - wie in diesem Beispiel die Voraussetzung dass er kopierbar ist.)



  • ps:

    @xe-li sagte in Initialisierung und Variablen Deklaration:

    Generics sind eine schöne Sache, dar das Programm zur Laufzeit den Typ selbst bestimmen kann.

    Erstmal gibt es in C++ keine "Generics". Es gibt Templates, die werden auch gerne mal als Generic Types bezeichnet, aber den Begriff "Generics" kenne ich nur von C#.

    Und: zur Laufzeit passiert da gar nix. C++ ist vollständig statisch typisiert, der Typ jeder Variable wird bei der Übersetzung festgenagelt. Was bei Templates passiert ist lediglich dass man Code schreiben kann der Placeholder für Typen wie T verwendet, und diesen Code kann man dann mit unterschiedlichen Typen verwenden. Man muss es aber irgendwo festnageln. Der Compiler baut dann anhand der Schablone (=das Template) neuen Code, wo er halt die Platzhalter (T) durch die konkreten Typen ersetzt. Funktionen oder allgemein Ausdrücke die mal nen int und mal nen double zurückgeben/ergeben sind in C++ nicht möglich.



  • @hustbaer sagte in Initialisierung und Variablen Deklaration:

    Und: zur Laufzeit passiert da gar nix. C++ ist vollständig statisch typisiert, der Typ jeder Variable wird bei der Übersetzung festgenagelt.

    C++ ist nicht statisch typisiert, da man zur Laufzeit polymorphen Variablen neue Typen zuweisen kann. Wenn man nachladbare Module verwendet (geht nur über systemspezifische Erweiterungen) dann kann man sogar Typen verwenden, die zum Übersetzungszeitpunkt des Hauptprogramms gar nicht existierten. Allerdings ist das Dispatching statisch, da die Aufrufkonventionen beim Übersetzen des Hauptprogramms festgelegt wurden. D.h. man kann nur abgeleiteten Typen verwenden. Das Duck Typing anderer Sprachen bzw. der Templates funktioniert in C++ zur Laufzeit nicht.



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


Log in to reply