Konstruktor und Destruktor
-
Hallo verwende ich den Konstruktor und den Destruktor hier sinnvoll ?
Oder kann man das noch besser lösen ?
#include <iostream> using namespace std; class addition { private: int z1; int z2; public: int add( ); addition ( int zahl_1 , int zahl_2) { z1 = zahl_1; z2 = zahl_2; } ~addition() { cout<<"Destruktor"<<endl; } }; int addition :: add() { int erg; erg = z1 + z2; cout<<"Erg: " << erg << endl; return erg; } int main() { addition calc(1,1); // objekt anlegen und dem konstruktor mit werten initialisieren calc.add(); // die funktion add aufrufen { addition dtor ( NULL,NULL ) ; // desturktor aufrufen // der konstrutkor hat 2 parameter also // braucht der destrutkor auch 2 parameter } addition s( 2,2); // konstruktor mit neuen werten initialisieren s.add(); { addition dtor ( NULL,NULL ) ; // destruktor erneut aufrufen } system("PAUSE"); }
-
Grundsätzlich ist eine Addition beileibe nichts, was man als Klasse modellieren würde.
Darüber hinaus ist dein Code inhaltlich nicht sinnvoll. Die Zeilen 53 und 63 sind völlig sinnlos. Du erzeugst dort neue Objekte mit den Namen dtor, die sofort wieder zerstört werden. Ein Destruktor wird normalerweise am Ende der Lebensdauer eines Objekts automatisch aufgerufen, und man kann ihm auch niemals Argumente übergeben.
NULL ist auch keine Zahl, warum nicht einfach 0?
-
hiho,
also den Destruktor rufst du in deinem Programm nirgends manuell auf.
{ addition dtor ( NULL,NULL ) ; // Konstruktoraufruf }Hierbei erzeugst du ein Objekt namens "dtor" (Konstruktorauruf) und übergibst 2x NULL, damit ist z1=0 und z2=0.
-
dest schrieb:
Hallo verwende ich den Konstruktor und den Destruktor hier sinnvoll ?
Ich werde mal den (Un-)Sinn der Klasse nicht hinterfragen... Einen Destruktor kannst du in diesem Fall weglassen, und solltest statt einer nachträglichen Zuweisung im Konstruktorrumpf lieber die Initialisierungsliste des Konstruktors verwenden:
addition(int zahl_1, int zahl_2) : z1(zahl_1), z2(zahl_2) { }
-
Ab wann muss man den denn Destruktor manuell Aufrufen ?
Weil hier wird der ja jetzt automatisch aufgerufen.
Ich werde mal den (Un-)Sinn der Klasse nicht hinterfragen...
Das ist nur eine Übung für mich um zu sehen wie man mit Konstruktoren und Destruktoren arbeiten kann. #include <iostream> using namespace std; class addition { private: int z1; int z2; public: int add( ); addition ( int zahl_1 , int zahl_2) : z1 ( zahl_1 ) , z2 ( zahl_2) { } ~addition() { cout<<"Destruktor"<<endl; } }; int addition :: add() { int erg; erg = z1 + z2; cout<<"Erg: " << erg << endl; return erg; } int main() { // http://fredosaurus.com/notes-cpp/oop-condestructors/constructors.html { addition calc(1,1); // objekt anlegen und dem konstruktor mit werten initialisieren calc.add(); // die funktion add aufrufen } // hier wird der destruktor automatisch aufgerufen system("PAUSE"); }
-
hiho,
den Destruktor musst du bei der dynamischen Speicherverwaltung (new/delete) indirekt aufrufen, mittels delete bzw. delete[] (bei Arrays) Operator.
Bei allem Anderen braucht dich das nicht zu interessieren,
weil, wie du schon gesagt hast, der Destruktor automatisch,
beim Verlassen des Güligkeitsbereiches, aufgerufen wird.
-
dest schrieb:
Ab wann muss man den denn Destruktor manuell Aufrufen ?
In der Regel garnicht.
-
dest schrieb:
Ab wann muss man den denn Destruktor manuell Aufrufen ?
Als Anfänger kannst du erstmal davon ausgehen: niemals.
Ich behaupte mal das mindestens 95% der C++Programmierer niemals in die Situation kommen, in dem sie ein Destruktor manuell aufgerufen müssen.
-
Dweb schrieb:
den Destruktor musst du bei der dynamischen Speicherverwaltung (new/delete) manuell aufrufen, mittels delete bzw. delete[] (bei Arrays) Operator.
Selbst da rufst du den Destruktor nicht selbst auf (sondern nur indirekt).
-
Habe mal ein Beispiel gemacht:
#include <iostream> class Foo { public: ~Foo() { std::cout << "Destruktor" << std::endl; } }; Foo f_global; int main() { { Foo f_lokal; } // <-- f_lokal wird zerstört (automatisch). Foo* p = new Foo; delete p; // Hier musst du den Destruktor nun indirekt über den delete Operator aufrufen. system("pause>nul"); return 0; } // <-- f_global wird zerstört (automatisch). /* Insgesamt wurde der Destruktor nun also 3x augerfuen. */
-
Dweb schrieb:
Habe mal ein Beispiel gemacht:
Und nochmal: Auch hier hast du den Destruktor NICHT manuell aufgerufen. Das delete ihn aufruft ist ein Implementierungsdetail.
// Das wäre ein manueller Aufruf: A a; a.~A(); // In der Regel niemals nötig
-
~a();Das ist kein expliziter Aufruf des Destruktors.
Ein solcher müsste so aussehena.~A();
-
camper schrieb:
~a();Das ist kein expliziter Aufruf des Destruktors.
Ein solcher müsste so aussehena.~A();Da merkt man schon wie selten man so etwas braucht

-
Egal wie selten ich es brauchen werde. ^^
Wenn man weiss wie es geht dann schadet es auch wohl nicht. ^^
Danke für die Hilfen.
-
dest schrieb:
Wenn man weiss wie es geht dann schadet es auch wohl nicht. ^^
Solange man nicht weiss, in welchen Situationen manuelle Destruktoraufrufe sinnvoll sind, nützt einem die Information auch nichts.

asc hat schon Recht. Du fährst besser damit, Destruktoren gar nie direkt aufzurufen.
-
Hi Nexus,
Nexus schrieb:
dest schrieb:
Wenn man weiss wie es geht dann schadet es auch wohl nicht. ^^
Solange man nicht weiss, in welchen Situationen manuelle Destruktoraufrufe sinnvoll sind, nützt einem die Information auch nichts.

asc hat schon Recht. Du fährst besser damit, Destruktoren gar nie direkt aufzurufen.
Dann lass uns mal an deinem Wissen teilhaben.
In welchen Situationen benutzt man denn manuelle Destruktor-Aufrufe?
Ich habe nämlich auch keine Ahnung
Ich rate mal: Vielleicht wenn man die Speicheranforderungen für new und delete neudefiniert?Gruß,
CSpille
-
CSpille schrieb:
Ich rate mal: Vielleicht wenn man die Speicheranforderungen für new und delete neudefiniert?
Ja. Solche Low Level Sachen.
Man könnte es bestimmt sonst auch noch für diverse schmutze Hacks benutzen.
-
dest schrieb:
Egal wie selten ich es brauchen werde. ^^
Wenn man weiss wie es geht dann schadet es auch wohl nicht. ^^
Doch kann es schaden.
Wenn du weisst wie, könntest du auf die Idee kommen es irgendwann zu verwenden. Wenn dir irgendwann aber das nötige Hintergrundwissen fehlt, um es richtig zu machen, machst du irgendwann Unsinn.
-
z.Bsp. immer beim zerstören, mit placement new`s erzeugter, objekte...
char* two_objects = operator new[sizeof(T)*2]; T* first = new(two_objects ) T(/*ctor-parameter*/); T* second = new(two_objects+sizeof(T)) T(/*ctor-parameter*/); /*iwas mit first und second machen*/ first ->~T(); second->~T(); operator delete[] two_objects;T ist natürlich als template-Parameter zu verstehen...
bb
-
sollte man mit placement new erzeugte objekte nicht auch mit placement delete wieder freigeben?