konstruktor mit ungueltigem parameter?



  • was passiert wenn ich ein objekt bei der erzeugung initialisieren will, aber ungueltige parameter verwende. wird der fuer das objekt allozierte speicher wieder freigegeben? ist die art und weise der pruefung so ok?

    im folgenden beispiel darf nicht mit 0 initialisiert werden. d.h. was passiert wenn ich mit 0 initialisiere?

    class bigobj
    {
      private:
      int m_fd;
      char m_big[1000];
    
      public:
      bigobj::bigobj();
      bigobj::bigobj(int afd);
      virtual bigobj::~bigobj();
    
    }
    

    und

    bigobj::bigobj(int afd)
    {
      if (afd == 0)
      {
         return -1
      }
      else
        m_fd = afd;
    }
    


  • wenn ein ctor fehlschlaegt, zB weil die parameter falsch waren - dann musst du eine exception werfen.



  • was waere dann im obrigen beispiel mit dem allozierten speicher z.b. fuer die priavten datenelemente.

    wie wuerde der speicher freigegeben?
    oder muss ich das im catch block machen - aber wie?



  • Memberobjekte und automatische Objekte werden freigegeben, sowie natürlich der Speicher, den der Konstruktor selbst belegt:

    class Class {
      int x, y;
      OtherClass o;
    public:
      Class() { if (blub) throw something(); }
    };
    

    => alles klar, x und y werden natürlich freigegeben, der Destruktor von o wird aufgerufen.

    Was nicht passiert: Dass der eigene Destruktor aufgerufen wird (dazu müßte ein gültiges Objekt existieren, und das ist ja noch nicht der Fall, wenn der Konstruktor eine Exception wirft). Dh folgendes Beispiel verursacht ein Speicherloch:

    class Class {
      int *x;
    public:
      Class(int y) {
        x = new int[y];
        if (blub) throw something();
      }
      ~Class() { delete[] x; }
    };
    

    Das Problem kann man entweder durch try..catch lösen, oder indem man Handle-Objekte verwendet, wie z.b. auto_ptr oder Container, statt nackten Pointern.



  • danke 🙂



  • Wenn ich mich nicht ganz täusche, ist es auch erlaubt im Konstruktor delete this aufzurufen. Damit wäre das Speicherproblem gelöst. Die Verwendung von delete this ist aber in mehrerer Hinsicht kritisch. Unter anderem müsste sichergestellt werden, dass dein Objekt nur auf dem Heap mittels new erzeugt wird, da delete nicht auf Objekte im Stack angewendet werden darf.



  • Was für ein Speicherproblem? Wenn der Konstruktor etwas wirft, wird das Objekt, so wie es ist, wieder gelöscht.



  • Fluxx schrieb:

    Die Verwendung von delete this ist aber in mehrerer Hinsicht kritisch. Unter anderem müsste sichergestellt werden, dass dein Objekt nur auf dem Heap mittels new erzeugt wird, da delete nicht auf Objekte im Stack angewendet werden darf.

    delete this ist im Konstruktor in jedem Fall falsch. Wenn ich

    Foo *f = new Foo;
    

    schreibe, und der Konstruktor von Foo wirft eine Exception (d.h. nachdem der Speicher reserviert wurde), wird die Allokation rückgängig gemacht. Gibst du den Speicher schon im Konstruktor frei, wird derselbe Speicher zweimal freigegeben, was normalerweise keine erfreulichen Auswirkungen auf den weiteren Programmlauf hat.


Anmelden zum Antworten