Seite 1 von 1

Standardkonform? Objekt in Methode zerstören und neu machen

Verfasst: 14.04.2013, 13:03
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?

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

Verfasst: 14.04.2013, 13:09
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.

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

Verfasst: 14.04.2013, 13:18
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 …

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

Verfasst: 14.04.2013, 13:37
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().

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

Verfasst: 14.04.2013, 13:39
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.

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

Verfasst: 14.04.2013, 15:04
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.

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

Verfasst: 14.04.2013, 15:09
von Krishty
hmmmm. Nein; ich modifiziere ihn nicht; weder im Speicher noch abstrakt (dafür ist Placement new ja da).

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

Verfasst: 14.04.2013, 15:23
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 ]

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

Verfasst: 14.04.2013, 15:34
von Krishty
Großartig; Dankeschön!