Löschen von static membern und "verzögerte" Initialisierung von const membern



  • Abend,

    ich habe 2 kleine C++ Fragen (die nichts miteinander zu tun haben):

    1. Gibt es eine Möglichkeit const Variablen zu einem späteren Zeitpunkt zu initalisieren? Sagen wir ich habe einen DWORD pointer, den ich jedoch nicht bei der Definition sondern zu einem späteren Zeitpunkt A initialisieren will. Nach Zeitpunkt A soll er jedoch nie mehr geändert werden. Das einzige was mir dazu einfällt wäre sowas:
    const DWORD* foo;
    // ...
    foo = new DWORD[10];
    const_cast<DWORD*>(foo)[0] = 2;
    

    Gibt es da vllt noch eine andere Möglichkeit?

    1. Gibt es eine "Standardlösung" zum Löschen von statischen Membern? Sagen wir ich habe so eine Klasse:
    class Foo {
    public:
      Foo();
      ~Foo();
      static int* p;
    };
    

    und nehmen wir an es gibt sehr viele Instanzen von Foo. Wenn mein Dtor nun so aussieht:

    Foo::~Foo() {
       delete p;
       p=0;
       // Nicht-statische member löschen
    }
    

    dann wird viele tausende Male delete auf ein einen Null-Zeiger aufgerufen. Ist zwar in Ordnung, aber schöne wäre es doch, wenn das delete nur einmal aufgerufen werden würde. Dazu könnte ich eine statische lokale variable nehmen:

    static bool called = false;
    if(!called) {
       called = true;
       delete p;
    }
    

    Und alternativ könnte ich auch einen statischen "Dtor" anlegen: static void StaticDestructor(), der dann alle statischen Member löscht und den ich einfach manuell aufrufe.
    Wie löscht ihr also dynamisch allokierten Speicher, der von static Member referenziert wird?



  • this->that schrieb:

    1. Gibt es eine Möglichkeit const Variablen zu einem späteren Zeitpunkt zu initalisieren? Sagen wir ich habe einen DWORD pointer, den ich jedoch nicht bei der Definition sondern zu einem späteren Zeitpunkt A initialisieren will. Nach Zeitpunkt A soll er jedoch nie mehr geändert werden.

    Wie wär's mit sowas hier?

    const DWORD* foo;
    // ...
    DWORD *bar = new DWORD[10];
    foo = bar;
    bar[0] = 2;
    

    this->that schrieb:

    Foo::~Foo() {
       delete p;
       p=0;
       // Nicht-statische member löschen
    }
    

    dann wird viele tausende Male delete auf ein einen Null-Zeiger aufgerufen. Ist zwar in Ordnung, aber schöne wäre es doch, wenn das delete nur einmal aufgerufen werden würde.

    Wer allokiert p denn? Die Deallokation würde ich entsprechend dazu machen, also wenn z.B. das erste Foo-Objekt den Speicher bereitstellt, dann sollte auch erst das letzte Foo ihn wieder löschen. So wie das bei dir im Moment aussieht, mußt du nur einmal ein einziges Foo löschen, und schon hast du einen Haufen Foos, die plötzlich ohne p dastehen...



  • dooooomi schrieb:

    Wie wär's mit sowas hier?

    Hehe, kurz nach dem Posten ist mir auch diese Lösung eingefallen. So werde ichs auch machen.

    dooooomi schrieb:

    Wer allokiert p denn? Die Deallokation würde ich entsprechend dazu machen, also wenn z.B. das erste Foo-Objekt den Speicher bereitstellt, dann sollte auch erst das letzte Foo ihn wieder löschen. So wie das bei dir im Moment aussieht, mußt du nur einmal ein einziges Foo löschen, und schon hast du einen Haufen Foos, die plötzlich ohne p dastehen...

    Ja, das stimmt. Wäre in meinem konkreten Fall jedoch kein Problem, da ich ALLE Foo Objekte auf einmal allokiere und alle auch wieder auf einen Schlag deallokiere. Ich machs jetzt einfach so, dass die Klasse die die Foo's und p allokiert das p einmalig wieder freigibt (eine allgemeinere Lösung wäre wohl über einen Referenzzähler).



  • Jetzt bin ich doch noch über ein kleines Problem gestoßen. Mein foo ist in Wirklichkeit ein Doppelzeiger:

    const DWORD** foo;
    

    und ich habe nun folgendes probiert:

    const DWORD** foo;
    DWORD** bar = new DWORD*[N];
    // bar füllen
    foo = bar;
    

    Leider führt die letzte Zuweisung zu dem Fehler "error C2440: '=' : cannot convert from 'DWORD **' to 'const DWORD **'
    Hat mich erstmal verwundert, denn schließlich geht das ja auch:

    const DWORD* foo;
    DWORD* bar = new ...
    foo = bar
    

    Sehe ich das richtig, dass die einzige Möglichkeit foo nun doch zu initialisieren so aussieht:

    const DWORD** foo;
    DWORD** bar = new DWORD*[N];
    // bar füllen
    for(...)
       foo[i] = bar[i];
    

    ?





  • hustbaer schrieb:

    const DWORD*const* foo;
    

    Hm, dann gibt es ja auch ein

    const DWORD* const * const foo = 0;
    

    C++ ist schon krank. 😃



  • this->that schrieb:

    C++ ist schon krank. 😃

    Nun ja, ich weiß ja nicht wie jemand "C++" programmiert, aber Doppelzeiger etc. sind meines Erachtens in C++ eher die Ausnahme als die Regel (Bis auf an C-Kompatiblen DLL-Schnittstellen brauchte ich sowas jedenfalls nie).



  • this->that schrieb:

    Hm, dann gibt es ja auch ein

    const DWORD* const * const foo = 0;
    

    C++ ist schon krank. 😃

    Du sagst es!
    Und dieser Thread zeigt wieder mal wunderbar, daß C++ Programmierer sehr viel Zeit investieren müßen, um die Mängel ihrer Programmiersprache zu umgehen. Wie soll man dabei produktiv sein?



  • c++ just sucks.doesnt it? schrieb:

    this->that schrieb:

    C++ ist schon krank. 😃

    Du sagst es!
    Und dieser Thread zeigt wieder mal wunderbar, daß C++ Programmierer sehr viel Zeit investieren müßen, um die Mängel ihrer Programmiersprache zu umgehen. Wie soll man dabei produktiv sein?

    Nur weil einer meint, kranke Konstrukte verwenden zu müssen, hat dies nichts mit dem Rest zu tun. In der freien Wildbahn trifft man sowas unter echten C++Programmierern wohl nicht an (Echt meine ich: keine C mit Klassen-Programmierer).

    Man kann eine Sprache schlechter machen als sie ist, aber dann bitte mit praxisrelevanten.



  • asc schrieb:

    Man kann eine Sprache schlechter machen als sie ist, aber dann bitte mit praxisrelevanten.

    Ist klar. Der OP ist natürlich ein Hobbyprogrammierer, der die äußersten Grenzen von C++ ausloten möchte.



  • asc schrieb:

    Nur weil einer meint, kranke Konstrukte verwenden zu müssen, hat dies nichts mit dem Rest zu tun. In der freien Wildbahn trifft man sowas unter echten C++Programmierern wohl nicht an (Echt meine ich: keine C mit Klassen-Programmierer).

    Fast hätte ich eine ähnliche Antwort geschrieben. Dann dachte ich jedoch, dass es einen unregistrierten Troll mit dem Nick "c++ just sucks.doesnt it?" nicht wert wäre...


Anmelden zum Antworten