delete this im Konstruktor?
-
Chris++ schrieb:
Ich will gar nichts damit machen. Ich habs nur in unserem Projekt gefunden
Prinzipiell verstehe ich warum derjenige das gemacht hat. Er wollte wohl verhindern das ein Objekt erstellt wird sobald gewisse Daten (noch?) nicht geladen wurden.Für genau sowas gibt es Exceptions, vielleicht solltet ihr die bei Euch mal einführen :p
-
so gar das geht
class Lustig { private: long a; public: void print() { cout << "Hallo" << endl; }; }; Lustig *test = NULL; int main(int argc, char *argv[]) { test->print(); }
-
KingOfTheBlueMouse schrieb:
so gar das geht
was bedeutet "geht" bei dir?
-
Chris++ schrieb:
David_pb schrieb:
Hi!
Was genau willst du egtl mit diesem Unsinn bezwecken???
Wieso sollte man ein Objekt beim erstellen zerstören wenn du es doch sowiso weiterverwenden willst? Und warum sollte man es überhaupt erst erstellen wenn man es sowiso gleich wieder zerstört? :-Sgrüße
Ich will gar nichts damit machen. Ich habs nur in unserem Projekt gefunden
Prinzipiell verstehe ich warum derjenige das gemacht hat. Er wollte wohl verhindern das ein Objekt erstellt wird sobald gewisse Daten (noch?) nicht geladen wurden.Leider gibt new trozdem die Adresse das angelegten Objektes mit und man kann später nicht herausfinden ob es nun gültig ist oder nicht. Das ist also eine Tretmine für's Release.
danke für eure Antworten
Wow, das nenn ich mal schlechten Programmierstil... Sry, aber wer kommt denn auf so bescheuerte Gedanken?
grüße
-
es wird "hallo" aus gegeben
und alles laüft normal
-
David_pb schrieb:
Wow, das nenn ich mal schlechten Programmierstil... Sry, aber wer kommt denn auf so bescheuerte Gedanken?
grüße
also völlig bescheuert ist das ja nun nicht - nur nicht konsequent zu ende gedacht.
KingOfTheBlueMouse schrieb:
es wird "hallo" aus gegeben
und alles laüft normalvielleicht. vielleicht auch nicht - besonders bei vollmond. die eigenheiten einer bestimmten implementation (selbst wenn das bei den meisten compilern so sein sollte) interessieren in diesem forum nur bedingt. was hat das mit dem topic zu tun?
-
ich wollte damit nur anmerken das man sich in c/c++ selbst um den speicher kümmern muss
das beispiel von mir geht weil ich auf kein speicher zugreife hat also eigentlich garnichts hier mit zu tun
-
David_pb schrieb:
Chris++ schrieb:
David_pb schrieb:
Hi!
Was genau willst du egtl mit diesem Unsinn bezwecken???
Wieso sollte man ein Objekt beim erstellen zerstören wenn du es doch sowiso weiterverwenden willst? Und warum sollte man es überhaupt erst erstellen wenn man es sowiso gleich wieder zerstört? :-Sgrüße
Ich will gar nichts damit machen. Ich habs nur in unserem Projekt gefunden
Prinzipiell verstehe ich warum derjenige das gemacht hat. Er wollte wohl verhindern das ein Objekt erstellt wird sobald gewisse Daten (noch?) nicht geladen wurden.Leider gibt new trozdem die Adresse das angelegten Objektes mit und man kann später nicht herausfinden ob es nun gültig ist oder nicht. Das ist also eine Tretmine für's Release.
danke für eure Antworten
Wow, das nenn ich mal schlechten Programmierstil... Sry, aber wer kommt denn auf so bescheuerte Gedanken?
grüße
Keine Ahnung. Ich weis nicht wer das geschrieben hat. Ich finde auch das es sinnvoller ist dieses "Daten.Geladen" vorher abzufragen und dann erst ein Objekt zu erstellen ...
-
camper schrieb:
das objekt (sofern wir annehmen es existiert bereits) wird zerstört - danach wird der konstruktor normal verlassen, ergo haben wir dann ein existierendes zerstörtes objekt :p
Ja, das meinte ich auch mit
Undefiniert wäre es für mich nur, wenn [...] der Instanzzeiger danach in irgendeiner Form inner- oder ausserhalb der Klasse benutzt wird.
Das Objekt wurde zerstört, auch wenn es für den Client so aussieht, als wenn es nach new gerade erzeugt wurde. Ein nachfolgender Zugriff auf das Objekt führt somit unweigerlich zu UB.
camper schrieb:
interessant wäre noch, was im falle eines virtuellen geerbten destruktors passiert - ich bin mir jetzt nicht mal sicher, welcher dann ausgeführt wird. nehmen wir an es ist der geerbte. dann haben wir anschließend ein objekt, dessen basis nicht mehr lebt - selbst wenn das kein problem ist: es gibt keine möglichkeit dieses objekt dann später zu zerstören
Was ja auch nicht nötig wäre, es wurde ja bereits komplett zerstört.
KingOfTheBlueMouse schrieb:
es wird "hallo" aus gegeben
und alles laüft normalUndefiniertes Verhalten schliesst aber auch den Fall ein, dass alles "normal" läuft.
Und wie camper schon sagte, beim nächsten Vollmond kann das ganz anders aussehen.
Chris++ schrieb:
Ich will gar nichts damit machen. Ich habs nur in unserem Projekt gefunden
Prinzipiell verstehe ich warum derjenige das gemacht hat. Er wollte wohl verhindern das ein Objekt erstellt wird sobald gewisse Daten (noch?) nicht geladen wurden.Dann kannst du ihm ja jetzt zeigen, wie man's richtig macht.
-
groovemaster schrieb:
camper schrieb:
interessant wäre noch, was im falle eines virtuellen geerbten destruktors passiert - ich bin mir jetzt nicht mal sicher, welcher dann ausgeführt wird. nehmen wir an es ist der geerbte. dann haben wir anschließend ein objekt, dessen basis nicht mehr lebt - selbst wenn das kein problem ist: es gibt keine möglichkeit dieses objekt dann später zu zerstören
Was ja auch nicht nötig wäre, es wurde ja bereits komplett zerstört.
nur die basis. der "most-derived"-konstruktor wurde danach noch normal beendet - folglich existiert da immer noch etwas - hohles :p
-
Also entweder verstehe ich dich nicht, oder du hast einen Denkfehler. Denn egal wo du delete this aufrufst, in Base oder Derived, das Objekt wird _komplett_ zerstört, also auch der komplette Speicher freigegeben. Ein weiteres Zerstören von irgendwas ist nicht mehr notwendig.
-
objektzerstörung und speicherfreigabe sind ja zwei verschiedene dinge, die speicherfreigabe macht mir auch keine sorgen. wohl aber
#include <iostream> struct A { A() { std::cout << "A ctor\n"; } virtual ~A() { std::cout << "A dtor\n"; } }; struct B : A { B() { std::cout << "B ctor\n"; delete this; } ~B() { std::cout << "B dtor\n"; } }; struct C : B { int* p; C() { p = new int; std::cout << "C ctor\n"; } ~C() { delete p; std::cout << "C dtor\n"; } }; int main() { new C; }
das halbfertige objekt wird zerstört und dann geht die konstruktion munter weiter - ups.
-
Wiedemauchsei, ein delete this im Konstruktor ist Mist!
-
camper schrieb:
das halbfertige objekt wird zerstört und dann geht die konstruktion munter weiter - ups.
Ahh, ok. Jetzt hab ich verstanden, was dich stört. Naja, du hast ja schon ein etwas extremeres Beispiel konstruiert, was sich aus dem Code des OP nicht ablesen lässt. Dazu kann ich eigentlich auch wieder nur sagen
Undefiniert wäre es für mich nur, wenn der Standard etwas sagt wie "ein dtor darf erst aufgerufen werden, nachdem der ctor aufgerufen wurde"
und das muss in deinem Beispiel ja mindestens für die Initialisierungsliste vom C ctor passiert sein. Ansonsten gibt es gar keine Möglichkeit, kein undefiniertes Verhalten zu erzeugen.
-
Habe nicht die große Programmiererfahrung wie viele andere hier, also korrigiert mich bitte wenn ich jetzt falsch liege.
Um auf das Anfangsbeispiele von Chris++ zurück zu greifen:
class Container { public: Container(bool DeleteMe) {if(DeleteMe) delete this;}; void SetzeWert(int wert) {m_wert = wert;}; int HoleWert() {return m_wert;}; private: int m_wert; }; //..... int main() { Container *Eimer = NULL; Eimer = new Container(true); Eimer->SetzeWert(5); //5 wird gesetzt int bla = Eimer->HoleWert(); //5 wird zurückgegebe delete Eimer; //unbehandelte Ausnahme bla = Eimer->HoleWert(); return 0; }
Nach meiner Meinung ist das Verhalten hier schon definiert!!!
Es wird ein Container-Objekt erstellt und durch den Konstruktor gleich wieder zerstört. Also der physikaliche Speicher, an dem das Objekt erstellt wurde, für andere sachen in diesem Programm wieder frei gegeben.(Speicherinhalt wurde mit werten für ein Objekt des Types Container gefüllt)
Sofort nach dem Erstellen/Zerstören des Objektes wird hier auf den Speicher zugegriffen (Funktionsaufruf). Da er jedoch noch nicht mit anderen Werten Überschrieben worden ist und zu dem Speicherbereich des Programmes gehört, meckert weder der Compiler, noch stürzt das Programm ab!!Jetzt kommt der Knackpunkt!!!
Würde nach dem Erstellen/Zerstören eine andere Variable deklariert werden,
würde der Speicher in dem das Objekt erstellt/zerstört wurde überschrieben werden.
Erst jetzt steht "mist" im Speicher welches das Programm zum Absturz bringen würde.
-
Riker schrieb:
Sofort nach dem Erstellen/Zerstören des Objektes wird hier auf den Speicher zugegriffen (Funktionsaufruf). Da er jedoch noch nicht mit anderen Werten Überschrieben worden ist und zu dem Speicherbereich des Programmes gehört, meckert weder der Compiler, noch stürzt das Programm ab!!
Für dich mag der Speicher noch vorhanden und nicht überschrieben worden sein. Das weisst du, weil du vermutlich die Architektur deines Systems kennst. Aus C++ Sicht ist das aber anders. Der Speicher wurde freigegeben und ist damit nicht mehr existent, oder besser, definiert. Weder der Inhalt noch die physische Präsenz sind definiert. Und damit ist es nicht zulässig, auf diesen nun "toten" Bereich zuzugreifen. Und wie ich weiter oben schon sagte, undefiniertes Verhalten schliesst auch ein, dass unter gegeben Umständen alles fehlerfrei funktionieren kann.