Ist das legal?



  • Im Constructor geht's ziemlich sicher nicht. Aber wenn du eine Exception wirfst, wird der Speicher auch freigegeben (automatisch). Der destructor wird aber nicht aufgerufen, weil das Objekt noch nicht fertig constructed war. Alle member der Klasse, die schon ordnungsgemäß constructed waren, werden auch kontrolliert zerstört.



  • Gehen sollte es beides, aber die Frage nach dem Sinn stellt sich viel schneller.

    Vor allem macht es im destructor keinen sinn, denn der wird ja nur aufgerufen, wenn du delete anwendest. Soweit ich das kenne constructor bei new destructor bei delete. Ganz einfache sache, weshalb das auch keinen sinn macht. dies beeeantwortet auch, weshalb das auch im constructor gehen wird, da der ja dann nur den destructor aufruft. Also geht beides, aber es macht keins davon sinn.

    mfg
    Freshman



  • Es sollten nicht mehr weiter Vermutungen aufgestellt werden. Wenn jemand seine Antwort mit den Standard untermauern kann, dann soll er sich melden. Ich werd irgendwann mal reinschauen, aber es dauert halt immer seine Zeit, dort was brauchbares zu finden.



  • regnad schrieb:

    void MyClass::Destroy(void)
    {
        delete this;
    }
    

    Dazu sollte es auch FAQ-Beiträge geben: Ja, ist legal. Das Objekt darf natürlich nicht auf dem Stack liegen.

    MyClass::MyClass(void)
    {
        delete this;
    }
    

    Das ist nicht möglich, da das Objekt im Block des Konstruktors noch nicht fertig konstruiert wurde. Wüsste aber auch nicht, wozu das gut sein sollte.

    Vielleicht könnte man das nachmachen, indem man eine Exception wirft und in einem function try block auffängt? Naja...



  • operator void schrieb:

    MyClass::MyClass(void)
    {
        delete this;
    }
    

    Das ist nicht möglich, da das Objekt im Block des Konstruktors noch nicht fertig konstruiert wurde. Wüsste aber auch nicht, wozu das gut sein sollte.

    Wenn ich mich nicht sehr irre ist das Objekt sehr wohl im Block des Konstruktors "fertig". Du darfst afaik nur in der Initialisierungsliste nicht auf *this zugreifen.



  • Wenn es da fertig ist, warum wird dann, wenn ich eine Exception werfe der Konstruktor verlassen, kein Destruktor aufgerufen und das Objekt existiert nicht?



  • Btw. wenn der Destruktor virtual ist, dann ist das auf jeden Fall auch nicht erlaubt, weil man dann eine Funktion einer nicht initialisierten Unterklasse aufrufen könnte...



  • Jester schrieb:

    Btw. wenn der Destruktor virtual ist, dann ist das auf jeden Fall auch nicht erlaubt, weil man dann eine Funktion einer nicht initialisierten Unterklasse aufrufen könnte...

    wie meinst du? im konstruktorkörper sind doch schon alle basisklassenkonstruktoren aufgerufen worden?
    vielleicht steht im kapitel über lifetime im standard was darüber, die beginnt auf jedenfall erst nach ende des ctors und endet mit dem eintritt in den dtor. d.h. die lebenszeit dieses objekts würde aufhören, bevor sie begonnen hat. unlogisch? aber verboten?

    operator void schrieb:

    [
    Vielleicht könnte man das nachmachen, indem man eine Exception wirft und in einem function try block auffängt? Naja...

    das böseste was es gibt 😉



  • davie schrieb:

    wie meinst du?

    Angenommen der Destruktor wäre virtual und die Basisklasse ruft delete this auf... dann wird doch der Destruktor der Unterklasse aufgerufen... und die ist noch nicht konstruiert.



  • Jester schrieb:

    Angenommen der Destruktor wäre virtual und die Basisklasse ruft delete this auf... dann wird doch der Destruktor der Unterklasse aufgerufen... und die ist noch nicht konstruiert.

    Sicher?
    Normales virtual Dispatching läuft ja auch nicht ab...



  • #include <set>
    #include <iostream>
    #include <conio.h>
    using namespace std;
    
    class X;  
    set<X*> setX;  
    set<X*>::iterator pos;
    
    class X
    {
    public:
      unsigned getNum() const {return refCount;}
    
      X()
      {
          inc();
          setX.insert(this);
          cout << "ctor" << " " << refCount << endl;
          delete this; // Selbstmord im Konstruktor! ;-)
      }
    
      ~X()
      {
          dec();
          setX.erase(this);
          cout << "dtor" << " " << refCount << endl;
      }  
    
    private:  
      static int refCount;
      void inc(){refCount++;}
      void dec(){refCount--;}  
    };
    
    int X::refCount = 0;
    
    int main()
    {
      unsigned zahl = 0;
      X* px = new X[20];
    
      for( pos = setX.begin(); pos != setX.end(); ++pos)
      {
          zahl++;
          cout << zahl << " " << *pos << " " << (*pos)->getNum() << endl;
      }
    
      delete[] px; 
    
      zahl = 0;
      for( pos = setX.begin(); pos != setX.end(); ++pos)
      {
          zahl++;
          cout << zahl << " " << *pos << " " << (*pos)->getNum() << endl;
      }
    getch();
    }
    

Anmelden zum Antworten