Wie prüfen, ob Objekt instanziiert ist?



  • Hi,

    wie prüft man in C++ eigentlich, ob ein (Member-)Objekt bereits instanziiert wurde?

    In Java geht das ja so:

    House myHouse;
    ...
    
    House getMyHouse() {
      if (myHouse == NULL)
        myHouse = new House();
    
      return myHouse;
    }
    


  • Hallo,

    wenn du die Instanz dynamisch angelegt hast, kannst du prüfen, ob der Zeiger ungleich 0 ist (wobei er auch != 0 und trotzdem ungültig sein kann).

    House *h;
    
    House * getHouse() {
      if (h==0)
        h = new House;
      return h;
    };
    

    MfG

    GPC



  • In C++ gibt es keine nicht instantiierten Objekte. Entweder ein Objekt existiert oder eben nicht. Am ehesten dem Java-Konzept eines Objektes entspricht der Pointer (oder noch besser der smart-pointer). Ein Pointer kann irgendwohin zeigen. Ein Zeiger, der auf kein Objekt verweisen soll, wird normalerweise mit 0 initialisiert. Dann kannst Du den Zeiger auf 0 abfragen.



  • GPC schrieb:

    wenn du die Instanz dynamisch angelegt hast, kannst du prüfen, ob der Zeiger ungleich 0 ist

    Wobei das nur bei new(nothrow) sinnvoll ist, new liefert immer einen gültigen Zeiger.



  • groovemaster schrieb:

    GPC schrieb:

    wenn du die Instanz dynamisch angelegt hast, kannst du prüfen, ob der Zeiger ungleich 0 ist

    Wobei das nur bei new(nothrow) sinnvoll ist, new liefert immer einen gültigen Zeiger.

    whoop, stimmt. Hatt ich vergessen. Dank dir.



  • Hallo,

    Danke für eure Anmerkungen.

    Worin besteht denn dann der Unterschied zwischen

    House* myHouse = new House;
    
    House* myHouse = new House();
    

    und

    House myHouse = House();
    

    ?

    Und wenn man Klassenobjekte immer als Pointer instanziiert, wann und wozu benutzt man dann Variante 3?

    Gruß, Thomas



  • Nr. 1 und 2 sollten äquivalent sein (kann auch sein, dass der Compiler das Zweite als Funktionspointer interpretiert, da bin ich mir aber nicht sicher).
    Variante 3 ist eigentlich nie sinnvoll. Du erzeugst mit House() ein temporäres Objekt (mit dem Standardkonstruktor, womit dann per Kopierkonstruktor myHouse initialisiert wird. Das Verhalten kannst du billiger haben, wenn du einfach

    House myHouse;
    

    schreibst, das ruft den Standardkonstruktor direkt auf.



  • Nr. 1 und 2 sollten äquivalent sein (kann auch sein, dass der Compiler das Zweite als Funktionspointer interpretiert, da bin ich mir aber nicht sicher).

    Funktionspointer? Wieso das? 1 und 2 sind meines Wissens komplett identisch. Bei 2 wird halt explizit angegeben, welcher Konstruktor aufgerufen wird, bei 1 wird implizit der Standardkonstruktor genommen.



  • House* myHouse;
    

    definiert einen Zeiger auf ein Objekt der Klasse House. Es wird keine Instanz angelegt.

    House* myHouse = new House;
    

    definiert einen Zeiger auf ein Objekt der Klasse House und initialisiert den Zeiger mit einem dynamisch erzeugten Objekt.

    House myHouse;
    

    definiert eine Instanz der Klasse House. Hier wird das Objekt auch mit dem Konstruktor initialisiert.

    Der Unterschied ist wesentlich. Im 3. Fall kannst Du Dich darauf verlassen, daß Du ein gültiges Objekt hast. Wenn die Variable myHouse ungültig wird - und sei es durch eine Exception, wird auch automatisch der Destruktor aufgerufen. Wenn im 1. Fall und 2. Fall die Variable den Scope verläßt, passiert gar nichts. Im 2. Fall hättest Du einen Speicherleck.

    Ich empfehle, wenn möglich, den 3. Fall zu verwenden. Das verhindert Speicherlecks und ist nebenbei auch noch schneller, da kein dynamischer Speicher alloziiert werden muß. Pointer sollte man vermeiden. Pointer haben die unangenehme Eigenschaft, daß sie nicht initialisert sein können und keinen Einfluß auf die Lebensdauer der Objekte haben, was aber bewußt eingesetzt genau gewünscht sein kann.

    Pointer haben allerdings den Vorteil, daß sie auf abgeleitete Klassen zeigen können. So ist beispielsweise so etwas möglich:

    House *myHouse = new Hochhaus
    

    Dagegen macht folgendes keinen Sinn:

    House myHouse = Hochhaus().
    

    Das zweite bewirkt, daß eine temporäre Instanz vom Typ Hochhaus angelegt wird und der Copy-Konstruktor von House aufgerufen wird, welcher ein Objekt vom Typ House erzeugt. Die temporäre Instanz wird dann aufgeräumt.


Anmelden zum Antworten