Konstruktor und Destruktor



  • N00b Alarm

    Hallo ich arbeite gerade ein Buch über Cpp durch welches schon etwas älter ist aber ist ja nicht so wichtig, zu Problem.

    Ich habe folgendes program abgeschrieben, es funktioniert auch und ich verstehe es...

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    class Cat
    {
        public:                     // Beginn der Klassendeklaration
            int GetAge();           // Zugriffsfunktion
            void SetAge(int age);   // Zugriffsfunktion
            void meow();            // Allgemeine Funktion
    
        private:                    // Beginn des privaten Abschitts
            int itsAge;             // Elementvariable
    };
    
    // Die oeffentlich Zugriffsfunktion GetAge gibt
    // den Wert des Datenelements itsAge zurueck.
    
    int Cat::GetAge()
    {
        return itsAge;
    }
    
    //Definition der oeffentlichen
    // Zugriffsfunktion SetAge.
    // Gibt Datenelement itsAge zurueck.
    void Cat::SetAge(int age)
    {
        // Elementvariable itsAge auf den als
        // Parameter age uebergebenen Wert sezten.
        itsAge = age;
    }
    
    //Definition der Methode Meow
    // Rueckgabe: void
    // Parameter: Keine
    //Aktion: Gibt "miau" auf dem Bildschirm aus.
    void Cat::meow()
    { 
        cout << "Miau" << endl;
    }
    
    //Eine Katze erzeugen, Alter festlegen, Mmieauen lassen
    // Alter mitteilen lassen, dann erneut miauen.
    
    int main(int argc, char *argv[])
    {
    
        int age;
    
        Cat Luzi;
        Cat Kimi;
        cout << "Wie alt ist Luzi? >> ";
            cin >> age;
            cout << endl;
    
        Luzi.SetAge(age);
    
            cout << "Wie alt ist Kimi? >> ";
            cin >> age;
            cout << endl;
    
        Kimi.SetAge(age);
    
        Luzi.meow();
    
        cout << "Luzi ist " << Luzi.GetAge() << " Jahre alt." << endl;
    
        Luzi.meow();
        Kimi.meow();
    
        cout << "Kimi ist " << Kimi.GetAge() << " Jahre alt." << endl;
    
        Kimi.meow();
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    dann sollte das ganze beispiel darauf umgeschrieben werden
    zwecks der Demonstration von Konstruktor und Destruktor

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    class Cat                       // Beginn der Klassendeklaration
    {
         public:                    // Beginn des oeffentlichen Abschnitts
       ->    Cat(int initialAge);    // Konstruktor
       ->   ~Cat();                 // Destruktor
            int GetAge();           // Zugriffsfunktion
            void SetAge(int age);   // Zugriffsfunktion
            void meow();            // Allgemeine Funktion
    
        private:                    // Beginn des privaten Abschitts
            int itsAge;             // Elementvariable
    };
    
    (hier)
    //Konstruktor von Cat
    Cat::Cat(int initialAge)
    {
        itsAge = initialAge;
    }
    (hier)
    //Destruktor
    Cat::~Cat()
    {
    }
    
    // Die oeffentlich Zugriffsfunktion GetAge gibt
    // den Wert des Datenelements itsAge zurueck.
    
    int Cat::GetAge()
    {
        return itsAge;
    }
    
    //Definition der oeffentlichen
    // Zugriffsfunktion SetAge.
    // Gibt Datenelement itsAge zurueck.
    void Cat::SetAge(int age)
    {
        // Elementvariable itsAge auf den als
        // Parameter age uebergebenen Wert sezten.
        itsAge = age;
    }
    
    //Definition der Methode Meow
    // Rueckgabe: void
    // Parameter: Keine
    //Aktion: Gibt "miau" auf dem Bildschirm aus.
    void Cat::meow()
    { 
        cout << "Miau" << endl;
    }
    
    //Eine Katze erzeugen, Alter festlegen, Mmieauen lassen
    // Alter mitteilen lassen, dann erneut miauen.
    
    int main(int argc, char *argv[])
    {
    
        int age;
    
        Cat Luzi;
        Cat Kimi;
        cout << "Wie alt ist Luzi? >> ";
            cin >> age;
            cout << endl;
    
        Luzi.SetAge(age);
    
            cout << "Wie alt ist Kimi? >> ";
            cin >> age;
            cout << endl;
    
        Kimi.SetAge(age);
    
        Luzi.meow();
    
        cout << "Luzi ist " << Luzi.GetAge() << " Jahre alt." << endl;
    
        Luzi.meow();
        Kimi.meow();
    
        cout << "Kimi ist " << Kimi.GetAge() << " Jahre alt." << endl;
    
        Kimi.meow();
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    dann bekomme ich eine Fehlermeldung vom Compiler

    --->
    In function int main(int, char**)
    no matching function for call to Cat::Cat
    canidates are Cat::Cat(Const Cat&
    Cat::Cat(int)

    Warum?
    das mit dem Konstruktor und Destruktor verstehe ich nioch nicht ganz, ich möchte aber jetzt bitte nur wissen warum das beispiel aus dem Buch nciht funktioniert.

    Danke



  • Wie du der Fehlermeldung deines Compilers entnehmen kannst, benötigst du einen Default-Ctor, d.h. einen Ctor, der keine Argumente erwartet, um folgendes zu schreiben:

    Cat Luzi;
    Cat Kimi;
    

    Mit den bisherigen Ctoren kannst du ein Objekt vom Typ Cat nur erstellen, indem du du das Alter bereits bei der Initialisierung an das Objekt übergibst, bzw. mit dem Copy-Ctor eine Kopie eines anderen bestehenden Objekts erstellst.

    Ließ am besten nochmal die entsprechenden Kapitel in deinem C++-Buch 🙂

    Gruß Caipi



  • Du hast ja das folgende:

    Cat(int initialAge);
    
    Cat Luzi; 
    Cat Kimi;
    

    Du hast ja nur einen Konstruktor, der einen int Wert erwartet, aber du hast keinen standard Konstruktor, der keinen Wert erwartet wie:

    Cat();
    

    So weiss der Compiler nicht, was er mit den Zeilen

    Cat Luzi; 
    Cat Kimi;
    

    tun soll, du müsstest also z.B.:

    Cat Luzi(4);
    Cat Kimi(10);
    

    schreiben, oder noch den anderen Konstruktor einfügen.

    Edit: Da wahr wohl einer schneller 😃 😉



  • Vielleicht wundert dich jetzt, das

    Cat Luzi;
    Cat Kimi;
    

    nicht mehr funktiniert, obwohl man doch Objekte normalerweise so erstellen kann.
    Dazu musst du wissen (wie bereits erläutert), dass der Code gleichbedeutend ist mit:

    Cat Luzi ();
    Cat Kimi ();
    

    Also einem Konstuktoraufruf ohne Parameter.
    Dieser "Standartkonstruktor" ohne Parameter wird zusammen mit einem sog.
    standart Copy-Konstruktor jedem Objekt vom Compiler automatisch zur Verfügung
    gestellt. Das bedeutet, einer Klasse A, wie folgt definiert

    class A
    {
    public:
       int a;
    };
    

    steht automatisch der parameterlose Konstruktor zur Verfügung,
    so dass

    A My_A;  //== A My_A ();
    

    zulässig ist.
    Sobald du dir aber einen eienen Konstruktor schreibst, z.B.

    class A
    {
    public:
       int a;
       A (int b) {a=b;}
    }
    

    wird der Standartkonstruktor A () von A (int b) "überschrieben"!
    Das bedeutet, A () steht nicht mehr zur Verfügung was dazu führt:

    A My_A;        //Fehler! (== A My_A (), und A::A () gibt es nicht mehr, da           
                   //von A::A (int b) "überschrieben"
    A My_A2 (3);   //OK!!
    

    Das Problem kannst du einfach dadurch lösen, das du einen eigenen parameterlosen
    Konstruktor schreibst.

    class Cat                        // Beginn der Klassendeklaration
    {
         public:                     // Beginn des oeffentlichen Abschnitts
       ->    Cat(int initialAge);    // Konstruktor
       ->   ~Cat();                  // Destruktor
       ->    Cat () {}               // Eigener parameterloser Konstruktor
            int GetAge();            // Zugriffsfunktion
            void SetAge(int age);    // Zugriffsfunktion
            void meow();             // Allgemeine Funktion
    
        private:                     // Beginn des privaten Abschitts
            int itsAge;              // Elementvariable
    };
    

    nun dürfte es keine Probleme mehr geben!



  • wawawa schrieb:

    Vielleicht wundert dich jetzt, das

    Cat Luzi;
    Cat Kimi;
    

    [...] dass der Code gleichbedeutend ist mit:

    Cat Luzi ();
    Cat Kimi ();
    

    Träum weiter! Da ist überhaupt nichts gleich.



  • Cool-O-Meter |XXXXXX----| schrieb:

    wawawa schrieb:

    Vielleicht wundert dich jetzt, das

    Cat Luzi;
    Cat Kimi;
    

    [...] dass der Code gleichbedeutend ist mit:

    Cat Luzi ();
    Cat Kimi ();
    

    Träum weiter! Da ist überhaupt nichts gleich.

    Um es auch für alle verständlich zu formulieren:
    Zweiteres sind Funktionsdefinitionen. Es bleibt nur die erstere Schreibweise, oder aber X x = X();



  • Danke, jetzt dürfte ich es verstanden haben, aber ich lese trotzdem nochmal das kapitel...

    bis dann


Anmelden zum Antworten