Logikproblem bei der Vererbung [gelöst]



  • Ich schreibe ein kleines Textspielchen, und da ist ja Handlung sehr wichtig.
    Ich habe mich entschieden, das mit Spielhandlungsklassen zu regeln. Die haben alle eine Mutterklasse, bei der vor allem der Konstruktor wichtig ist.
    Die ID der Tochterklasse (ist eine Membervariable) wird dabei dabei dem Teil meines Programms übergeben, der sich um die Spielstanddatei kümmert.
    Ich hab das so geregelt:

    class Handlung
    {
    public:
        Handlung()
        {
            speicherId = this->id;
        }
        long id;
    };
    
    class Starthandlung : public Handlung
    {
    public:
        Starthandlung() {}
        long id = 1;
    };
    
    int main()
    {
        Starthandlung instanz;
    }
    

    Ich hatte erwartet, dass this->id auf die id-Variable von Starthandlung zeigt. Aber der Ausdruck hat einen zufällig wirkenden Wert.
    Das passiert normalerweise bei Variablen, denen noch kein Wert zugewiesen wurde, also scheint es sich um die id-Variable der Mutterklasse zu handeln.
    Wie kann ich aber auf die ID der Tochterklasse zugreifen? Muss ich einen Getter virtual long& getId() = 0; vererben oder geht das irgendwie anders?



  • Du initialisierst keine der Variablen.
    Im Konstruktor der Basisklasse kannst du nicht auf Werte einer abgeleiteten Klasse zugreifen, da sie noch nicht "vorhanden" sind.



  • manni66 schrieb:

    Du initialisierst keine der Variablen.
    Im Konstruktor der Basisklasse kannst du nicht auf Werte einer abgeleiteten Klasse zugreifen, da sie noch nicht "vorhanden" sind.

    Dankeschön.
    Dass die Variable in Starthandlung nicht initialisiert ist, ist mein Fehler (zu stark gekürzt). Ich änder das schnell oben.
    Der zweite Satz sagt schon alles, was ich wissen muss.



  • Eine kleine Frage noch:
    Kann ich den Basiskonstruktor auch gezielt mit Argumenten aufrufen und nicht nur automatisch?
    Dann könnte ich die ID als Argument übergeben.



  • Klar geht das. Aber du kannst natürlich nicht die Membervariable der abgeleiteten Klasse übergeben, die gibt's da ja noch nicht.



  • In deinem Beispielcode befindet sich keine Basisklasse. Meinst du

    class Starthandlung : public Handlung
    

    ?
    Und was hat es mit der (Member)Variablen 'speicherId' auf sich? Wo ist diese deklariert?



  • Das mit der fehlenden Vererbung war ein Versehen, hab's geändert.
    Die speicherId-Variable ist nirgendwo deklariert, das ist ja gekürzt hier. Ist halt das Teil, was bei Programmende gespeichert wird.



  • Mich hat nur gewundert, daß du in beiden Klassen eine Membervariable 'long id' hast.



  • Ist ID automatisch in der Unterklasse, wenn es auch in der Basisklasse ist? Wusste ich gar nicht.



  • Dafür gibt es ja Vererbung, damit Kind-Klassen die gleichen Eigenschaften und Funktionen bereitstellen können.



  • Wenn du also die Id in der Basisklasse speichern willst, dann benutze so etwas:

    class Handlung
    {
    public:
        Handlung(long id)
          : id(id) // <- Initialisierungsliste
        {
        }
    
        long Id() const { return id; }
    
    private:
        long id;
    };
    
    class Starthandlung : public Handlung
    {
    public:
        Starthandlung() : Handlung(1)
        {
        }
    };
    

    Falls dich die doppelten Bezeichner ('id') stören, dann kannst du ja eine der Namen ändern ('id_' oder 'm_id').

    Beachte aber, daß jetzt jedes Objekt 'StartHandlung' die gleiche Id hat (also hier 1).
    Wenn du doch je Objekt eine unterschiedliche Id haben willst (falls es also mehrere StartHandlung-Objekte gibt und du diese unterscheiden möchtest), so könntest du dies mit einer 'static'-Membervariablen lösen (welche bei jedem Objekt dann inkrementiert wird).



  • Interessant. An die Initialisierungsliste hatte ich gar nicht mehr gedacht.


Anmelden zum Antworten