Problem mit einer Aufgabe!



  • Hallo zusammen, habe folgende Aufgabe:

    a) Erklaeren Sie schriftlich den Ablauf des Programms, indem Sie die Ausgabe in eine Textdatei kopieren und fuer jede Zeile bzw. jeden zusammengehoerigen Block von Ausgabezeilen erklaeren, welche Funktion (welcher Konstruktor, Operator...) an dieser Stelle aufgerufen wird und warum dies geschieht, d.h. welcher Aufruf des Hauptprogramms den Funktionsaufruf aus welchem Grund ausgeloest hat.

    b) Fuehren Sie statische Variablen in die Klasse Sum ein, mit denen Sie zaehlen, wie oft die Konstruktoren, Operatoren und der Destruktor im Programm aufgerufen werden. Schreiben Sie zusaetzlich eine Methode, mit der Sie die Zaehlerstaende am Ende ausgeben. Ueberpruefen Sie die Zaehlerstaende, indem Sie sie mit der Anzahl der zu der jeweiligen Methode gehoerigen Ausgabezeilen des Programms vergleichen.Welcher theoretische Zusammenhang besteht zwischen dem Zaehlerstand des Destruktors und denen der Konstruktoren? Ueberpruefen und erklaeren Sie (schriftlich) anhand Ihrer Ergebnisse.

    Das zugehoerige Programm findet ihr unten:

    #include <iostream>
    
    using namespace std;
    
    // Zaehler fuer die Rekursionstiefe
    
    int Tiefe=0; 
    
    // Ausgabe von Leerzeichen:
    
    void Einruecken(int Anz)
    {
      for (int i=0; i<Anz; i++)
        { cout << "  ";}
    }
    
    // Klassendefinition
    
    class Sum
    {
      // Bildet die Summe der zahlen von 1 bis N, indem rekursiv Vorgaengerobjekte
      // N-1,...,1 angelegt werden und beim Anlegen dieser Objekte deren Werte von "N"
      // in S aufaddiert werden, oder indem zwei existente Objekte addiert werden.
    
      private:
    
        Sum* Vorg; // Zeiger auf Vorgaenger-Objekt
        int N;     // betrachtete Zahl
        int S;     // Summe von 1 bis N (=Summe der "N's" aller Vorgaengerobjekte
        	       // und des betrachteten Objekts selbst)
    
        // Zaehler fuer die Aufrufe der Methoden
    
        // --> hier einfuegen
    
      public:
    
        Sum();     		// Konstruktor ohne Parameter
        Sum(int);  		// Konstruktor mit einem Parameter
        Sum(const Sum&); 	// Copy-Konstruktor
        ~Sum(); 		// Destruktor
    
        // Methoden zum Setzen und Auslesen der Attribute
    
        void SetVorg(Sum* Vor) {Vorg=Vor; return;}
        void SetS(int Su)    {S=Su; return;}
        void SetN(int nN)    {N=nN; return;}
    
        Sum* GetVorg()  {return Vorg;}
        int  GetN()	    {return N;}
        int  GetS()     {return S;}
    
        Sum operator= (const Sum&); 
    
        // Methode zur Ausgabe der Zaehlerstaende
    
        // --> hier einfuegen
    
    };
    
    // Statische Datenelemente initialisieren
    
    // --> z.B. hier einfuegen
    
    Sum::Sum()
    {
      Tiefe++;
      Einruecken(Tiefe);
      cout << "Sum::Sum() begin." << endl; 
    
      // Daten setzen
    
      Vorg=0; N=1; S=1; 
    
      Einruecken(Tiefe);
      cout << "Sum::Sum() end." << endl; 
      Tiefe--;
    }
    
    Sum::Sum(int Zahl)
    {
      Tiefe++;
      Einruecken(Tiefe);
      cout << "Sum::Sum(int) begin." << endl;  
    
      // Daten setzen und ggf. neues Vorgaengerobjekt anlegen:
    
      if (Zahl>1)
        {
          N=Zahl;
          Sum* NewSum = new Sum(N-1); // neues Vorgaengerobjekt anlegen
          Vorg=NewSum;		  // Vorgaengerzeiger setzen
          S=N+Vorg->GetS();
        }
      else
        { 
          Vorg=0;      // kein neues Vorgaengerobjekt anlegen
          N=1;
          S=1; 
        }
    
      Einruecken(Tiefe);
      cout << "Sum::Sum(int) end." << endl;  
      Tiefe--;
    }
    
    Sum::Sum(const Sum& SumRef)
    {
      Tiefe++;
    
      // Daten setzen
    
      N=SumRef.N;
      S=SumRef.S;
    
      Einruecken(Tiefe);
      cout << "Sum::Sum(const Sum& SumRef) begin." << endl;  
    
      // Pruefen ob Vorgaengerobjekt existiert und ggf. auch dieses kopieren
    
      if (SumRef.Vorg!=0)
        { Vorg=new Sum(*(SumRef.Vorg)); }
      else
        { Vorg=0; }
    
      Einruecken(Tiefe);
      cout << "Sum::Sum(const Sum& SumRef) end." << endl;  
      Tiefe--;
    }
    
    Sum::~Sum()
    {
      Tiefe++;
      Einruecken(Tiefe);
      cout << "Sum::~Sum() begin.";
      cout << "N: " << N << " S: " << S << endl;
    
      // Objekt zerstoeren
    
      if (Vorg!=0)
        { delete(Vorg); }
    
      Einruecken(Tiefe);
      cout << "Sum::~Sum() end. " << endl;
      Tiefe--;
    }
    
    Sum Sum::operator = (const Sum& SumObj)
    {
      Tiefe++;
      Einruecken(Tiefe);
      cout << "Sum::operator= begin." << endl;
    
      // Daten setzen
    
      N=SumObj.N; 
      S=SumObj.S; 
    
      // Vorgaegerzeiger kopieren (keine neuen Vorgaengerobjekte anlegen)
    
      if (SumObj.Vorg!=0)
        { Vorg=new Sum(*(SumObj.Vorg)); }
      else
        { Vorg=0; }
    
      Einruecken(Tiefe);
      cout << "Sum::operator= end." << endl;
      Tiefe--;
      return *this;
    }
    
    // *********************************************************
    
    void PrintAll (Sum SumObj)
    { 
      // Ausgabe inclusive existierender Vorgaengerobjekte
    
      Tiefe++;
      Einruecken(Tiefe);
    
      cout << "PrintAll begin. N: " << SumObj.GetN() << " S: " << SumObj.GetS() << endl;
    
      // Ausgabe der Vorgaenger, falls existent
    
      if (SumObj.GetVorg()!=0) 
        {
          PrintAll(*(SumObj.GetVorg()));
        }
      else
        {
          Einruecken(Tiefe);
          cout << "Null pointer found. " << endl;
        }
      Einruecken(Tiefe);
      cout << "PrintAll end." << endl;
      Tiefe--;
      return;
    }
    
    Sum SumAdd (Sum SumObj1, Sum SumObj2)
    {
      Tiefe++;
      Einruecken(Tiefe);
      cout << "SumAdd begin." << endl;
    
      // Rueckgabeobjekt anlegen und belegen
    
      Sum RetObj; 
      RetObj.SetN(SumObj1.GetN()+SumObj2.GetN());
      RetObj.SetS(SumObj1.GetS()+SumObj2.GetS()+SumObj1.GetN()*SumObj2.GetN());
      RetObj.SetVorg(0);
    
      Einruecken(Tiefe);
      cout << "SumAdd end." << endl;
      Tiefe--;
      return RetObj;
    }
    
    int main()
    {
      cout << "Anfang: " << endl;
      Sum S1(3);
      Sum S2(2);
      Sum S3;
      PrintAll(S2);
      S3=SumAdd(S1,S2);
      PrintAll(S3);
      cout << "Ende. " << endl;
    
      return 0;
    }
    

    Ich danke allen die mir helfen!
    grüße



  • Ach und nochwas!

    Wenn ich das ganze dann compiliere dann kommt sowas heraus:

    Anfang:
      Sum::Sum(int) begin.
        Sum::Sum(int) begin.
          Sum::Sum(int) begin.
          Sum::Sum(int) end.
        Sum::Sum(int) end.
      Sum::Sum(int) end.
      Sum::Sum(int) begin.
        Sum::Sum(int) begin.
        Sum::Sum(int) end.
      Sum::Sum(int) end.
      Sum::Sum() begin.
      Sum::Sum() end.
      Sum::Sum(const Sum& SumRef) begin.
        Sum::Sum(const Sum& SumRef) begin.
        Sum::Sum(const Sum& SumRef) end.
      Sum::Sum(const Sum& SumRef) end.
      PrintAll begin. N: 2 S: 3
        Sum::Sum(const Sum& SumRef) begin.
        Sum::Sum(const Sum& SumRef) end.
        PrintAll begin. N: 1 S: 1
        Null pointer found.
        PrintAll end.
        Sum::~Sum() begin.N: 1 S: 1
        Sum::~Sum() end.
      PrintAll end.
      Sum::~Sum() begin.N: 2 S: 3
        Sum::~Sum() begin.N: 1 S: 1
        Sum::~Sum() end.
      Sum::~Sum() end.
      Sum::Sum(const Sum& SumRef) begin.
        Sum::Sum(const Sum& SumRef) begin.
        Sum::Sum(const Sum& SumRef) end.
      Sum::Sum(const Sum& SumRef) end.
      Sum::Sum(const Sum& SumRef) begin.
        Sum::Sum(const Sum& SumRef) begin.
          Sum::Sum(const Sum& SumRef) begin.
          Sum::Sum(const Sum& SumRef) end.
        Sum::Sum(const Sum& SumRef) end.
      Sum::Sum(const Sum& SumRef) end.
      SumAdd begin.
        Sum::Sum() begin.
        Sum::Sum() end.
      SumAdd end.
      Sum::operator= begin.
      Sum::operator= end.
      Sum::Sum(const Sum& SumRef) begin.
      Sum::Sum(const Sum& SumRef) end.
      Sum::~Sum() begin.N: 5 S: 15
      Sum::~Sum() end.
      Sum::~Sum() begin.N: 5 S: 15
      Sum::~Sum() end.
      Sum::~Sum() begin.N: 3 S: 6
        Sum::~Sum() begin.N: 2 S: 3
          Sum::~Sum() begin.N: 1 S: 1
          Sum::~Sum() end.
        Sum::~Sum() end.
      Sum::~Sum() end.
      Sum::~Sum() begin.N: 2 S: 3
        Sum::~Sum() begin.N: 1 S: 1
        Sum::~Sum() end.
      Sum::~Sum() end.
      Sum::Sum(const Sum& SumRef) begin.
      Sum::Sum(const Sum& SumRef) end.
      PrintAll begin. N: 5 S: 15
      Null pointer found.
      PrintAll end.
      Sum::~Sum() begin.N: 5 S: 15
      Sum::~Sum() end.
    Ende.
      Sum::~Sum() begin.N: 5 S: 15
      Sum::~Sum() end.
      Sum::~Sum() begin.N: 2 S: 3
        Sum::~Sum() begin.N: 1 S: 1
        Sum::~Sum() end.
      Sum::~Sum() end.
      Sum::~Sum() begin.N: 3 S: 6
        Sum::~Sum() begin.N: 2 S: 3
          Sum::~Sum() begin.N: 1 S: 1
          Sum::~Sum() end.
        Sum::~Sum() end.
      Sum::~Sum() end.
    

    Aber ich weiss nicht was ich mit dem ganzen anfangen soll!

    Grüße



  • Jede der Methoden gibt freundlicherweise aus, wo sie beginnt (z.B. " Sum::Sum(int) begin. " - der Ctor startet und wo sie endet (" Sum::Sum(int) end. ") und durch die Einrückungen solltest du eigentlich auch verfolgen können, welche dieser Aufrufe zusammengehören. Jetzt mußt du nur noch die Aufrufe, beginnend bei der main(), durch deinen Programmablauf verfolgen.


Anmelden zum Antworten