Rolf B: C++: char* behält zugewiesenen wert und std::string nimmt default an... wieso?

Beitrag lesen

Hallo hmm,

was Du da vorhast, ist ein Unfall der darauf wartet zu passieren. Grund: Statische Elemente einer Klasse werden nicht von ihrem Destruktor beeinflusst. Warum auch - es ist sinnlos bis falsch, beim Zerstören einer Instanz auch die statischen Elemente zu beseitigen.

D.h. du bist in deinem Destruktor auf die richtige Anordnung des Sourcecodes angewiesen, wenn Du auf irgendwas zugreifen willst, das nicht Teil dieser Klasseninstanz ist. Konstruktion und Destruktion erfolgen in entgegengesetzter Reihenfolge, das ist ein Stack, und weil du erst Bla erzeugst und dann a, wird zuerst a vernichtet und dann Bla.

Das Konstrukt class Bla {...} Bla; macht dreierlei: Es definiert (1) die Klasse Bla, (2) allociert es eine Variable namens Bla vom Typ class Bla und (3) registriert es diese Variable zur Destruktion. Erst nach wird eine Variable a vom Typ std:string deklariert, ein Objekt vom Typ std:string erzeugt und mit einem Leerstring initialisiert.

Trenne die Deklaration von class Bla und die Allocation der Variablen Bla, dann gehts:

using std;

class Bla
{
  public:
    static string a;
    static char* b;
    ~Bla()
    {
      cout << "A ist " << a << endl;
      cout << "B ist " << b << endl;
    }
};

string Bla::a = "";
char* Bla::b = "

Bla Bla;

irgendEinKlasse::FunktionDieAufgerufenWird()
{
  Bla::a = "test";
  Bla::b = "test";
}

Ich würde Dir aber eigentlich empfehlen wollen, das so nicht zu tun. Du schaffst damit implizite Abhängigkeiten, die auf der lexikalischen Reihenfolge der Elemente im Code basieren. Es ist robuster, solche Abhängigkeiten explizit zu machen.

D.h. statt eines static-Members a verwende ein non-static Member. Das ist dann eine normale Eigenschaft der Bla-Klasse, du kannst sie im Konstruktor von Bla initialisieren und dann ist eindeutig klar, dass es erst nach Ende des Destruktors von Bla zerstört wird.

Alle Zugriffe auf deine Map lässt Du dann über die Bla Variable laufen (für die du sicherlich noch einen besseren Namen findest, und Du solltest vielleicht auch Abstand davon nehmen, Klassen und Variablen gleich zu benennen - mich hat das erstmal verwirrt.

Dein std::... habe ich übrigens durch using std; ersetzt, und die printf durch cout. Musst nur an passender Stelle ein #include <iostream> hinzufügen (ohne .h dahinter!).

Tja, und wenn Du das Ende des Programms finden musst - was für ein Typ von Programm ist das denn? Du hast doch normalerweise immer irgendeine main() Funktion. Wenn die endet, endet auch das Programm.

Rolf

--
sumpsi - posui - clusi