vererbung etc.



  • Hi
    was genau macht:
    -----
    explicit InterfaceQuery(FMSInterfaces iid) : interfaceId(iid), itsInterface(0) {}
    -----
    so wie unten. Vielen Dank
    Michael

    ---------

    enum FMSInterfaces {
    FMSSystemInterface,
    FMSDatabaseInterface,
    FMSPadInterface,
    FMSIRSInterface,
    FMSPrefInterface
    };

    struct InterfaceQuery
    {
    explicit InterfaceQuery(FMSInterfaces iid) : interfaceId(iid), itsInterface(0) {}

    FMSInterfaces interfaceId;
    void* itsInterface;
    };



  • Das ist ein expliziter Konstruktor. Selbes gibt es auch beim std::vector. Beispiel:

    std::vector<int> v = 4; // Nicht erlaubt durch expliziten Konstruktor.
    std::vector<int> v(4); // 4 ints mit Wert 0 werden eingefügt
    

    Falls du das hinter dem Doppelpunkt meinst, das ist eine Initialisierungs-Liste. Normalerweise initialisiert man Variablen (und Basisklassen) in einer Initialisierungsliste. Bei const-Membern und Referenzen ist das sogar erforderlich.
    Beispiel:

    struct mit_init_list
    {
        const int const_i;
        int& ref;
    
        int* ptr; // Kann auch ohne init-liste initialisiert werden, dennoch ist sie zu bevorzugen
    
        mit_init_list(int& i)
            : const_i(i)
            , ref(i)
            , ptr(&i)
        {}
    };
    
    struct ohne_init_list
    {
         const int const_i;
         int& ref;
    
         int* ptr;
    
         ohne_init_list(int& i)
         {
             const_i = i; // Fehler, kann nicht an const-Variable zuweisen
             ref = i; // Tut nicht, was du glaubst. Führt möglicherweise (im besten Fall!) zu Programmabsturz
    
             ptr = &i; // Okay
         }
    };
    

    Ausnahmen bei der Initialisierungsliste kann man machen, wenn eine Exception auftreten könnte, die man noch im Konstruktor behandeln kann.



  • Vielen Dank
    was ist dies genau:
    itsInterface(0) {}

    hier wird eine Zeigeradresse übergeben?
    init_list(int& i)

    ohne explicit gibt das Fehler bei der
    Initialisierung? Ist das der Hauptgrund von explicit
    Verwendung?
    Dande und Gruss Michael


  • Mod

    Das int& ist kein Zeiger, Zeigerparameter werden mit * gekennzeichnet. Das ist eine Referenz. Ein ähnlicher Mechanismus wie ein Zeiger aber sicherer und leichter zu benutzen. Unbedingt mal im Lehrbuch nachgucken.

    Das explicit hat eine ganz andere Bedeutung als du denkst. Es verbietet dem Compiler, implizite Konvertierungen beim Konstruktoraufruf zu machen. Ein klassisches Beispiel wäre eine eigene Stringklasse mit Konstruktoren:

    class MyString {
    public: 
     MyString (int N);           // Erstellt einen MyString der Länge N
     SMytring (const char *text); // Erstellt einen MyString mit Inhalt test
    };
    

    Jetzt mal angenommen, du würdest einen MyString mit Inhalt "A" erstellen wollen, schreibst aber versehentlich

    MyString Foo = 'A';   // anstatt "A"
    

    Dann sieht der Compiler einen char ('A'). Einen char kann er implizit in int umwandeln und würde (da in diesem Beispiel der Konstruktor nicht explicit ist) den oberen Konstruktor mit dem Wert von 'A' (meistens 65) aufrufen. Also ganz ohne Warnung oder Fehler ein vollkommen unerwünschtes Verhalten durch einen kleinen Schreibfehler.
    Und dies hier war noch ein einfaches, sehr konstruiertes Beispiel. Es gibt weitaus komischere Umwandlungen an die man gar nicht denkt, was zu sehr schwer zu findenden Fehlern führen kann.

    Manche Leute sagen daher, dass man einparametrige Konstruktoren allgemein explicit machen sollte, außer man wünscht ausdrücklich dieses Verhalten. Möglich, dass sie recht haben.



  • Danke
    das:
    itsInterface(0) {}
    ist mir noch nicht klar. Zudem sehe ich einez Zugriff mit iid unten. Soll anscheinend nicht verlinkt sondern so ähnlich wie:
    http://www.osnews.com/story/24557/Torvalds_Android_GPL_Claims_Totally_Bogus_
    dort beschrieben ablaufen. rsp ich könne closed source machen (code unten) obwohl sein lib/dll code gpl ist. (mein erster Kodeschnipsel) Wie nennt man denn sowas und ich bekomme mit der iid Linie unten einen Fehler.
    Vielen Dank
    Michael

    case VASCORE::FSystem:
    {
    VASCORE::InterfaceQuery* iq = static_castVASCORE::InterfaceQuery*(param);
    switch (iq->interfaceId)
    {
    case InterfaceQuery(iid): // könnte falsch sein zumindest kapiere ich das nicht
    iq->itsInterface = static_cast<FMSSystem*>(VASCORE::global_FMS);

    break;
    default:
    std::abort();
    iq->itsInterface = 0;
    break;
    }


  • Mod

    mike4 schrieb:

    Danke
    das:
    itsInterface(0) {}
    ist mir noch nicht klar.

    Hast du dir mal angeguckt, was eine Initialisierungsliste ist? Vermutlich nein 🙄 .

    Das itsInterface(0) ist die Initialisierung des Members itsInterface mit 0, das {} ist der (leere) Funktionskörper des Konstruktors.

    Das sind grundlegendste Grundlagen für Klassen.



  • Danke schaue das gleich nochmals an und was ist der iid Funktion?



  • mike4 schrieb:

    Danke schaue das gleich nochmals an und was ist der iid Funktion?

    1. Der Funktion???
    2. iid ist keine Funktion. das sind aber wirklich absolute basics, was iid ist sollte dir nach den ersten 20-30 Seiten eines Einsteigerbuchs deiner Wahl eigentlich glasklar sein.

  • Mod

    mike4 schrieb:

    Danke schaue das gleich nochmals an und was ist der iid Funktion?

    Was soll damit sein? Das ist schlichtweg falsch, darum bekommst du auch einen Fehler. Switchmarken müssen Compilezeitkonstanten sein. Aber ich bin mir nicht einmal sicher, dass es das ist, was du suchst, so wie du den switch benutzt vermute ich, du hast keine Ahnung, was du da tust?



  • ja, also mein Code wird ein x-plane plugin also eine dll. Diese sollte eben via case die Flugsim Mitteilungen auswerten. Das wiederum ist alles in einer anderen GPL dll.
    https://github.com/PhilippMuenzel/vascore-embedded

    auch sowas gibt einen Fehler:
    case VASCORE::InterfaceQuery::interfaceId(iid):

    Fehler:‘VASCORE::InterfaceQuery::interfaceId’ cannot appear in a constant-
    expression

    Völlig neu für mich...dachte sowas ginge nur über Verlinken.


  • Mod

    mike4 schrieb:

    Völlig neu für mich...dachte sowas ginge nur über Verlinken.

    Ich habe dir doch gerade gesagt, was da los ist. Du verstehst noch nicht einmal die Antworten, wie willst du da selber programmieren?



  • logo wenn ich es wüsste, müsste ich ja niemanden überfordern.



  • SeppJ schrieb:

    mike4 schrieb:

    Danke schaue das gleich nochmals an und was ist der iid Funktion?

    Was soll damit sein? Das ist schlichtweg falsch, darum bekommst du auch einen Fehler. Switchmarken müssen Compilezeitkonstanten sein. Aber ich bin mir nicht einmal sicher, dass es das ist, was du suchst, so wie du den switch benutzt vermute ich, du hast keine Ahnung, was du da tust?

    (Hervorhebung von mir)

    Oder nochmal anders formuliert:
    Der Wert hinter der case-Marke muß bereits beim Compilieren bekannt sein, da kannst du nicht die Rückgabe einer Funktion verwenden. Aber da deine switch-Anweisung sowieso nur aus diesem falschen case und default besteht, dürfte eine normale if()-else Anweisung dort vollkommen ausreichen.



  • meine Frage bezog sich auf die Zeile mit iid (in der main.cpp vom obigen link)


Anmelden zum Antworten