Objekte, Scopes und Destruktoren
-
Hallo liebe Forengemeinde,
ich spiele gerade mit Objekten in Scopes herum. Dabei bin ich auf folgendes Problem gestoßen. Wieso führt der zweite Aufruf von p->say() auch zu einem "alive"? Der Destruktor wurde aufgerufen, wie er mitteilt. Trotzdem kann ich Funktionen eines toten Objekts aufrufen.
#include <iostream> #include <windows.h> using namespace std; class test{ public: test(){cout << "started";} ~test(){cout << "stopped";} void say(){cout << "alive";} }; int main() { test *p; { test t1; p=&t1; p->say(); system("pause"); } system("pause"); p->say(); system("pause"); }Das ganze soll die Grundidee dafür sein, dass in einer Funktion Objekte erzeugt werden und Zeiger auf diese in einer Liste gespeichert werden. Da nach Rückgabe der Funktion die Destruktoren aufgerufen werden, gibt mein Compiler Warnungen aus. Deshalb habe ich obigen Schnipsel konstruiert. Bitte um Klärung

-
Das nennt sich undefiniertes Verhalten - das Objekt wurde zerstört, aber davon bekommt der Zeiger nichts mit. Und dann rufst du eine Methode des ehemaligen Objekts auf. Das geht nur darum gut, weil diese Methode keine Member des Objekts ausnutzt.
-
In der Regel werden nicht-virtuelle Methodenaufrufe vom Compiler in einfache Funktionsaufrufe umgesetzt (halt mit verstecktem this-Parameter). Wird this dann nicht dereferenziert, läuft das Ganze durch - aber, wie CStoll richtig bemerkt, vom C++-Standard gedeckt ist das natürlich nicht.
Ein Compiler darf - und in ähnlichen Situationen tun gängige Compiler das mit entsprechenden Optionen auch - Code generieren, der so etwas verhindert. Es sollte mich nicht wundern, wenn gccs Mudflap oder MSVCs Debug-Modus darauf allergisch reagieren oder in zukünftigen Versionen reagieren werden. Auch können ganz generell Optimierungen zu seltsamen Effekten führen, wenn man undefiniertes Verhalten erzeugt - siehe beispielsweise diesen Artikel, der zwar C als Beispiel nimmt, aber Effekte beschreibt, die auch mit einem C++-Compiler passieren können.
-
OK danke für diese Hinweise
