Abfrageb, ob Objekt fehlerfrei erstellt wurde



  • Moin,

    Ihr seht im Titel, dass ich nicht mal weiß, nach welchen Schlagworten ich suchen soll.

    Bei der fstream-Klasse macht man ja sowas, um zu prüfen, ob eine Funktion richtig ausgeführt wurde:

    ifstream inputStream;
       inputStream.open("file.txt");
    
       if( !inputStream ) {
         cerr << "Error opening input stream" << endl;
       }
       // or
       if ( inputStream ) {
         // use inputStream
       }
    

    Ich finde dieses Vorgehen sehr elegant und möchte meine eigenen Klassen auch so implementieren, dass ich einfach das "Objekt abfrage", ob alles geklappt hat.

    Wie ist der Mechanismus dahinter?


  • Mod



  • EDIT: Habe das vor SeppJs Post geschrieben und beziehe mich nicht darauf!!

    Hi,

    ich muss gestehen, dass ich das gar nicht "elegant" finde.
    Exceptions wurden genau für sowas entworfen und sind da oftmals viel passender.
    Das Problem bei Gezeigtem ist, dass es dem Aufrufer ganz schnell passieren kann, diese Abfrage zu vergessen - und dann läuft er unbewusst in böse Fallen.

    Die Frage ist ja: Was soll ein Benutzer mit einem kaputten Objekt machen?
    (gerade weil er gar nicht unbedingt wissen kann, woran es gehakt hat).
    Bei den std::stream-Objekten muss man auch raten: Konnte man das File nicht öffnen? Ging die letzte Lese- oder Schreiboperation schief? und wenn ja: Warum? konnte das Gelesene nicht gewünscht interpretiert werden (Nondigit wo Zahl erwartet, ...) ? ....
    Das ist nicht trivial und spart überhaupt nichts ggü. Exceptions.

    Wenn das Objekt trotzdem benutzbar und/oder "reparierbar" ist, kann man das so wie oben gezeigt machen, indem man einen entsprechenden "cast-operator" definiert.

    z.B.

    struct myClass {
       operator bool() const { return ....  // hier wird der Status geprüft und entsprechend true oder false zurückgegeben
    

    Ein Anderes Problem dieser Herangehensweise liegt darin, dass damit überall ein impliziter cast gemacht werden kann - auch in Situationen, wo einem das nicht bewusst ist.

    Das führt zu häßlichen Effekten wie z.B. bei

    struct myClass {
       operator int() const;
    };
    
    void hallo(int i);
    
    int main() {
       int a1;
       myClass a2;
    
       hallo(a2); // hoppla! Gemeint war a1
    ...
    

    Das findet der Compiler in Ordnung. Das sieht jetzt sehr simpel aus, kann aber ziemlich häßlich sein - spätestens, wenn der Compiler über mehrere Stufen aus Allem Alles wandeln kann.

    Gruß,

    Simon2.



  • Naja, letztendlich heißt

    if( !inputStream )
    

    nichts anderes als

    if( inputStream  == false)
    

    oder auch

    if( inputStream == NULL)
    

    oder eben

    if( inputStream == 0)
    

    Im Prinzip heißt das nur, wenn dein File nicht geladen werden konnte dann ist der ursprüngliche Wert 0 noch vorhanden.



  • anti-freak schrieb:

    [...]

    Im Prinzip heißt das nur, wenn dein File nicht geladen werden konnte dann ist der ursprüngliche Wert 0 noch vorhanden.

    Mit den von Simon angesprochenen Konvertierungs-Problematiken. Der oben verlinkte Artikel diskutiert das ausführlicher.


Log in to reply