Standardkonform? Objekt in Methode zerstören und neu machen

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Standardkonform? Objekt in Methode zerstören und neu machen

Beitrag von Krishty »

Hi,

Normalerweise würde man eine Update()-Methode, die ein System an eine neue Umgebung anpasst, etwa so implementieren:

    void System::update() {
        destroyAllResources();
        createAllResourcesFromScratch();
    }


Ich möchte Zustand und Quelltext sparen indem ich es so mache:

    void System::update() {
        this->~System();
        new (this) System();
    }


Wird das durch irgendwas im C++-Standard verboten? Irgendeine bekloppte Klausel, dass die Lebenszeit des dynamischen Typs eines Objekts nicht während einer Methode enden darf oder so?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Standardkonform? Objekt in Methode zerstören und neu mac

Beitrag von Niki »

Die STL Allokatoren machen ja genau dasselbe. Zwar benutzen die da kein "this" für den Destructor- und Placement-New-Aufruf, aber was sollte das für einen Unterschied machen? Ich glaube kaum das der this-Pointer irgendwie von einem Constructor- oder Destructor-Aufrauf abhängig ist, sondern eher von Speicherreservierung/freigabe... und das tust du ja nicht. Muss auch so sein, denn ansonsten könnten die STL Allokatoren nicht funktionieren. Denk mal drüber nach, was beim Austauschen von Objekten in einem std::vector passiert. Nix anderes als das was du auch tust.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Standardkonform? Objekt in Methode zerstören und neu mac

Beitrag von Krishty »

Doch, das ist sogar sehr unterschiedlich – die STL-Allokatoren zerstören ja nicht sich selber sondern Objekte in dem Speicherbereich, den sie verwalten. Bei mir ist das Objekt, das zerstört wird, Teil der aktuellen Code-Ausführung (wir sind ja in einer Methode davon); bei der STL nicht. Ich habe deshalb Angst, in nicht-definiertes Verhalten zu treten …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4878
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Standardkonform? Objekt in Methode zerstören und neu mac

Beitrag von Schrompf »

Ich habe ehrlich keine Ahnung, was der Standard dazu sagt, aber ich habe das hier und da auch schon getan und bisher hat es immer prima funktioniert. Beweggrund war für mich genau der selbe: da baut man ein braves RAII-Objekt zusammen und dann braucht man wegen irgendeiner Spezial-Anforderung dann doch ein herzhaft zubeißendes Reset().
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Standardkonform? Objekt in Methode zerstören und neu mac

Beitrag von Niki »

Kristhy hat geschrieben:die STL-Allokatoren zerstören ja nicht sich selber sondern Objekte in dem Speicherbereich, den sie verwalten.
Ja, das habe ich schon so verstanden. Was ich meinte ist, dass das "technisch" (im Sinne von erzeugtem Code) eigentlich nichts ausmachen kann, da der this-Pointer lediglich eine Adresse auf den Anfang eines Objektes ist, welches du nicht freigibst. Aber du hast schon recht, dass irgendeine "bekloppte" Klausel das grundlos verbieten könnte.
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Standardkonform? Objekt in Methode zerstören und neu mac

Beitrag von eXile »

Kurze Antwort: Das geht nicht, weil du den this-Pointer modifizierst. Ich versuche, noch die entsprechenden Stellen aus dem Standard heraus zu suchen.

Oder änderst du ihn wirklich? Mmh, ich bin mir gerade unschlüssig. Warte mal. Nein, tust du natürlich nicht. Damit gibt es schon mal keine Probleme damit, dass der this-Pointer ein prvalue ist.
Zuletzt geändert von eXile am 14.04.2013, 15:11, insgesamt 1-mal geändert.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Standardkonform? Objekt in Methode zerstören und neu mac

Beitrag von Krishty »

hmmmm. Nein; ich modifiziere ihn nicht; weder im Speicher noch abstrakt (dafür ist Placement new ja da).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Standardkonform? Objekt in Methode zerstören und neu mac

Beitrag von eXile »

Ich hab's! (Entschuldige obigen Brainfart.)
N3337 3.8 Clause 7 hat geschrieben:If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that
pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can
be used to manipulate the new object, if:
  • the storage for the new object exactly overlays the storage location which the original object occupied, and
  • the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and
  • the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
  • the original object was a most derived object (1.8) of type T and the new object is a most derived object of type T (that is, they are not base class subobjects).

    [ Example:
    struct C {
      int i;
      void f();
      const C& operator=( const C& );
    };

    const C& C::operator=( const C& other) {
      if ( this != &other ) {
        this->~C(); // lifetime of *this ends
        new (this) C(other); // new object of type C created
        f(); // well-defined
      }
      return *this;
    }

    C c1;
    C c2;
    c1 = c2; // well-defined
    c1.f(); // well-defined; c1 refers to a new object of type C

    end example ]
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Standardkonform? Objekt in Methode zerstören und neu mac

Beitrag von Krishty »

Großartig; Dankeschön!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten