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.