Klausuraufgabe



  • ich habe in der klausur folgenden quellcode bekommen. Es soll die die Ausgabe des programmes hingeschreiben werden. allerdings versteh ich nicht was das Programm macht und hoffe das mir einer weiterhelfen kann... Vielen Dank im voraus!

    #include <iostream>
    using namespace std;
    
    class XXX
    {public:
        XXX() {++y;}
        ~XXX() {--y;}
    int gety() { return y;}
    private:
    static int y; 
    };
    
    int XXX::y=0;
    
    int main()
    { XXX a,b; 
        cout <<a.gety() <<endl; 
    {XXX a,b,c,d; 
        cout <<a.gety()<<endl;
    } 
    cout << a.gety() <<endl; 
    XXX c; 
        cout<<a.gety()<<endl; 
    {XXX* xPtr = new XXX;} 
        cout << a.gety() <<endl;
    }
    


  • Wenn ich nichts übersehen habe, ist dieses Beispiel etwas einfacher zu verstehen, als die anderen.

    Dazu ein paar Fragen im Vorfeld, um deinen Wissensstand zu überprüfen:

    * Was bedeutet "static"?
    * Was sind Konstruktor und Destruktor und wann werden sie aufgerufen?
    * Hast du dir inzwischen das Thema "Überdeckung von Variablen" angesehen?

    Falls mit irgendeinem Thema nichts anfangen kannst, solltest du dir das erstmal ansehen, bevor wir hier weitermachen.



  • * Was bedeutet "static"? // static speichert werte von variablen
    * Was sind Konstruktor und Destruktor und wann werden sie aufgerufen?
    // konstruktor ist eine Methode und wird bei der Erschaffung aufgerufen
    und destruktor ist auch eine methode und löscht objekte

    * Hast du dir inzwischen das Thema "Überdeckung von Variablen" angesehen?
    das hab ich nicht verstanden konnte nichts informatives finden



  • S.lukas schrieb:

    * Was bedeutet "static"? // static speichert werte von variablen

    nein.

    private:
      int m_x;
      static int s_x;
    

    wo ist der Unterschied zwischen m_x und s_x?

    S.lukas schrieb:

    * Was sind Konstruktor und Destruktor und wann werden sie aufgerufen?
    // konstruktor ist eine Methode und wird bei der Erschaffung aufgerufen
    und destruktor ist auch eine methode und löscht objekte

    jein. Der Destruktor löscht die Objekte, das stimmt schon. Aber er wird implizit aufgerufen.

    S.lukas schrieb:

    * Hast du dir inzwischen das Thema "Überdeckung von Variablen" angesehen?
    das hab ich nicht verstanden konnte nichts informatives finden

    {
    int a = 5;
    
    { // erzeuge inneren Scope
    int a = 6; // das "äußere a" wird überdeckt
    cout << a; // gibt das innere a aus
    } // Ende innerer Scope -> Ende Lebensdauer des inneren a
    
    cout << a; // gibt äußeres a aus
    }
    


  • vielen dank für deine hilfe bzw. information



  • wo ist der Unterschied zwischen m_x und s_x?

    unterschied ist das m_x int ist und
    s_x static. static speichert im durchlauf den wert und im nächsten durchlauf gibt er dsa gespeicherte aus?



  • nein. s_x ist genauso ein int wie m_x. "static" besagt in diesem Fall, dass alle Instanzen der Klasse auf dieselbe Variable zugreifen. Wenn also in einer Instanz s_x=5 gesetzt wird, gilt das in allen anderen Instanzen ebenso. m_x dagegen existiert in jeder Instanz unabhängig voneinander.

    Und um das Rätsel zu lösen: Die Klasse in deiner Übungsaufgabe beinhaltet einen Instanzenzähler. "gety()" liefert dir die Zahl der momentan existierenden Instanzen.



  • komm leider nicht auf die lösung was der compiler ausgibt



  • Die Ausgabe lautet:

    2
    6
    2
    3
    4



  • #include <iostream> 
    using namespace std; 
    
    class XXX 
    {public: 
        XXX() {++y;} //was passiert hier? wird sofort hochgezählt 
        ~XXX() {--y;} 
    int gety() { return y;} //gibt y zurück?
    private: 
    static int y; 
    }; 
    
    int XXX::y=0; //?
    
    int main() 
    { XXX a,b;  //?
        cout <<a.gety() <<endl; 
    {XXX a,b,c,d; //?
        cout <<a.gety()<<endl; 
    } 
    cout << a.gety() <<endl; 
    XXX c; //?
        cout<<a.gety()<<endl; 
    {XXX* xPtr = new XXX;} 
        cout << a.gety() <<endl; 
    }
    


  • S.lukas schrieb:

    #include <iostream> 
    using namespace std; 
      
    class XXX 
    {public: 
        XXX() {++y;} //was passiert hier? wird sofort hochgezählt --> Wenn es aufgerufen wird. Also, wenn Du ein Objekt von XXX erzeugst
        ~XXX() {--y;} 
    int gety() { return y;} //gibt y zurück? --> sehr gut! return bedeutet zurückgeben :P
    private: 
    static int y; 
    }; 
      
    int XXX::y=0; //? Die static Variabel y wird auf 0 gesetzt.
      
    int main() 
    { XXX a,b;  //? --> Ich lege zwei Objekte a, b vom Typ XXX an
        cout <<a.gety() <<endl; 
    {XXX a,b,c,d; //? --> siehe oben
        cout <<a.gety()<<endl; 
    } 
    cout << a.gety() <<endl; 
    XXX c; //? --> siehe oben
        cout<<a.gety()<<endl; 
    {XXX* xPtr = new XXX;} 
        cout << a.gety() <<endl; 
    }
    

    Ich an deiner Stelle würde konkrete Fragen stellen und zeigen, dass Du dich mit dem Thema auseinander setzt. Nach meinen Erfahrungen wird so ein Thread sonst sehr schnell geschlossen.

    LG, freakC++



  • daddy_felix schrieb:

    {
    int a = 5;
    
    { // erzeuge inneren Scope
    int a = 6; // das "äußere a" wird überdeckt
    cout << a; // gibt das innere a aus
    } // Ende innerer Scope -> Ende Lebensdauer des inneren a
    
    cout << a; // gibt äußeres a aus
    }
    

    Gibt es eine Möglichkeit die überdenkte Variable im Scope anzusprechen?
    Sowas ähnliches wie *this für Klassen etc?



  • {XXX* xPtr = new XXX;} // was wird hier gemacht?
        cout << a.gety() <<endl; 
    }
    


  • Schamote schrieb:

    daddy_felix schrieb:

    {
    int a = 5;
    
    { // erzeuge inneren Scope
    int a = 6; // das "äußere a" wird überdeckt
    cout << a; // gibt das innere a aus
    } // Ende innerer Scope -> Ende Lebensdauer des inneren a
    
    cout << a; // gibt äußeres a aus
    }
    

    Gibt es eine Möglichkeit die überdenkte Variable im Scope anzusprechen?
    Sowas ähnliches wie *this für Klassen etc?

    ::a für äußeres, a für inneres.

    S.lukas schrieb:

    {XXX* xPtr = new XXX;} // was wird hier gemacht?
        cout << a.gety() <<endl; 
    }
    

    Es wir ein Ptr auf XXX angelegt, dieser Pointer zeigt auf ein neu erschaffenes Objekt auf dem Heap vom Typ XXX. Im Prinzip wird nur ein weiteres XXX-Objekt angelegt.



  • Nathan schrieb:

    Schamote schrieb:

    daddy_felix schrieb:

    {
    int a = 5;
    
    { // erzeuge inneren Scope
    int a = 6; // das "äußere a" wird überdeckt
    cout << a; // gibt das innere a aus
    } // Ende innerer Scope -> Ende Lebensdauer des inneren a
    
    cout << a; // gibt äußeres a aus
    }
    

    Gibt es eine Möglichkeit die überdenkte Variable im Scope anzusprechen?
    Sowas ähnliches wie *this für Klassen etc?

    ::a für äußeres, a für inneres.

    S.lukas schrieb:

    {XXX* xPtr = new XXX;} // was wird hier gemacht?
        cout << a.gety() <<endl; 
    }
    

    Es wir ein Ptr auf XXX angelegt, dieser Pointer zeigt auf ein neu erschaffenes Objekt auf dem Heap vom Typ XXX. Im Prinzip wird nur ein weiteres XXX-Objekt angelegt.

    Ne. ::Identifier ist für global Scope. Hier gibts kein a im global Scope.



  • Nathan schrieb:

    S.lukas schrieb:

    {XXX* xPtr = new XXX;} // was wird hier gemacht?
        cout << a.gety() <<endl; 
    }
    

    Es wir ein Ptr auf XXX angelegt, dieser Pointer zeigt auf ein neu erschaffenes Objekt auf dem Heap vom Typ XXX. Im Prinzip wird nur ein weiteres XXX-Objekt angelegt.

    ... aber nicht wieder gelöscht. Dafür wäre ein "delete" notwendig.



  • wie kommt das ergebnis
    2
    6
    2
    3
    4



  • S.lukas schrieb:

    wie kommt das ergebnis
    2
    6
    2
    3
    4

    Richtig einrücken, dann sieht mans:

    int main()
    {
        XXX a/*1*/,b/*2*/;
        cout <<a.gety() <<endl; // 2
        {
            XXX a/*3*/,b/*4*/,c/*5*/,d/*6*/;
            cout <<a.gety()<<endl; // 6
        }/*5*/ /*4*/ /*3*/ /*2*/
    
        cout << a.gety() <<endl; // 2
    
        XXX c/*3*/;
        cout<<a.gety()<<endl; // 3
    
        {
            XXX* xPtr = new XXX/*4*/;
        }/*3*/
    
        cout << a.gety() <<endl; // 3
    }/*2*/ /*1*/ /*0*/
    


  • weil das so ist.

    Nimm dir mal den Code und kommentiere zu jeder(!) Zeile in der main(), wieviele Instanzen der Klasse nach Abarbeiten der jeweiligen Zeile deiner Meinung nach existieren.

    edit: hm... out hat dir ja schon die Antwort geliefert. Glück gehabt, brauchst nicht mehr übrlegen.

    edit2: out hat nen Fehler 😃 die mit "new" erzeugte Instanz wird nicht gelöscht!



  • out schrieb:

    {
            XXX* xPtr = new XXX/*4*/;
        }/*4*/
    
        cout << a.gety() <<endl; // 4
    }/*3*/ /*2*/ /*1*/ + Betriebssystem macht für dich noch ein delete: /*0*/
    

    Ach, da steht ein doofs new, Sorry.



  • vielen dank, an alle die sich beteiligt haben.
    ihr wart eine sehr sehr gute Hilfe.


Anmelden zum Antworten