"Sauberes" return



  • Hi Leute,
    Ich schreibe momentan ziemlich viele Funktionen, die zurückgeben können bzw. müssen, ob alles geklappt hat, oder nicht. Nur frage ich mich, nach dem Lesen von ziemlich viel Code anderer Leute, was denn die "sauberste" Möglichkeit dafür ist. Nehme man mal als Bsp. eine Texturen-Klasse, die mit SOIL arbeitet und eine Textur laden soll. Was wäre am saubersten...
    1.

    bool load(params)
      {
      ID = SOIL_load_OGL_texture(params);
      if(ID != 0)
        {
        return true;
        }
      else
        {
        return false;
        }
      }
    (...)
    unsigned int ID;
    
    bool load(params)
      {
      ID = SOIL_load_OGL_texture(params);
      if(ID == 0)
        {
        return false;
        }
      else
        {
        return true;
        }
      }
    (...)
    unsigned int ID;
    
    bool load(params)
      {
      ID = SOIL_load_OGL_texture(params);
      if(ID != 0)
        {
        return true;
        }
      return false;
      }
    (...)
    unsigned int ID;
    
    bool load(params)
      {
      ID = SOIL_load_OGL_texture(params);
      if(ID == 0)
        {
        return false;
        }
      return true;
      }
    (...)
    unsigned int ID;
    

    Danke schon mal im Voraus(Sone, falls du das liest: 😉 )

    MfG
    DragonRaider

    PS.: Sorry, falls das ins C Forum gehört



  • one word: exceptions



  • Hi dot,
    Ist OK. Nur das throw muss ich auch irgendwo hin setzen...
    Naja ich schätze mal die Form der Wahl wäre dann:

    void load(params)
      {
      ID = SOIL_load_OGL_texture(params);
      if(ID == 0)
        {
        throw "Unable to load texture!";
        }
      }
    (...)
    unsigned int ID;
    

    Oder habe ich dich da was falsch verstanden(habe zwar von throw gehört, es aber, bis jetzt, noch nie genutzt)?

    MfG
    DragonRaider



  • Ja, so geht es zwar, in der Regel schmeißt man aber eine Ausnahmeklassenobjekt.
    Die Standardbibliothek bietet hier eine ganze Hierachie an, die alle von std::exception abgeleitet sind.
    Dann kann man nämlich einfach

    try
    {
    
    }
    catch (std::exception &ex)
    {
    
    }
    

    um alle Ausnahmen zu fangen.



  • Der Vergleich (==) liefert bereits einen Wahrheitswert. Ein

    return ID != 0;
    

    wäre demnach übersichtlicher gewesen.

    Nichts desto trotz sind hier exceptions angebracht. Definiere jedoch eine eigene Ausnahmeklasse (z. B. von std::exception erben) und werfe nicht einfach einen string.

    Ave



  • Hi Nathan,
    Danke, für die Hilfe/den Tipp. Ich hab jetzt mal www.google.de befragt, da wird folgendes vorgeschlagen:

    struct myException : std::exception
    {
    const char* what() const noexcept
      {
      return "myException(description)";
      }
    };
    

    Entschuldigung, falls die Frage dumm ist, aber gibt es da auch noch ne "kürzere" Methode? Soweit ich den Code hier verstehe nein, aber...
    Danke schon mal bis hier hin 🙂 .

    MfG
    DragonRaider



  • Ja.
    Es gibt die Klasse "runtime_error", die für deine Fälle ausreicht.
    Im Konstruktor übergibst du einfach die Fehlermessage und kannst sie dann abfragen.



  • Nun, Exceptions vs Return-Values. Das haengt von Vorlieben, Objektinvarianten und Programmarchitektur. Ich persoenlich wuerde im vorliegenden Fall keine Exception werfen. Die Exception kann das Objekt in enem ungueltigen Zustand zuruecklassen. Ausserdem wuerden ueberall try-catches auftauschen. Ich wuerde die Texturklasse so gestallten, dass sie mit fehlerhaftem Laden umgehen kann. Das fehlerhafte Laden sollte in der Entwicklung trotzdem in einer Logdatei protokolliert werden.

    Eine Moeglichkeit, ist z.B. dass eine leere Textur ein gueltiger Zustand ist und alle Operationen mit Texturen damit umgehen muessen. Das fuehrt dann zu Code wie if(tex.valid()) { ... } else ( ... } und ist auch sehr unschoen.

    Meine bevorzugte Moeglichkeit, eine Dummytextur zu nutzen. D.h. bei Fehlschlag wird eine Dummytextur erzeugt. Das Dach des Hauses ist dann eben nicht braun, sondern ist weiss mit roter Schrift "Fix me". Nachfolgende Operationen brauchen sich dann keine Gedanken machen, ob die Textur gueltig ist. Sie ist es in jedem Fall. Wird die Dummytextur nicht algorithmisch generiert sondern ebenfalls irgendwann am Anfang des Programms geladen, dann wuerde ich eine Exception werfen.



  • Meine Texturklasse hat einen Default-Ctor, will man sie aber laden und das schlägt fehl gibts ne Exception. Und das ganze hat sogar noch eine starke Garantie.



  • starke Garantie

    Das bedeutet?



  • Die Textur an sich ist genau so wie vorher auch.



  • Hi,
    Ich finds echt "schön", dass sich hier so eine kleine Disskusion los getreten hat 🙂 . Ich denke, ich werde das mit der "Fix Me" Textur übernehmen und im Releasemode(ohne Konsole) dann auch eine "errors.txt" haben, in der Fehler, verursacht durch fehlende Texturen etc., genau mitgeloggt werden.
    Nun zur eigentlichen Frage:
    Wenn ich's mit ner boolschen Funktion löse, wäre denn dann 1., 2., 3. oder 4. am saubersten?
    MfG
    DragonRaider



  • Stechus Kaktus' Variante?


Anmelden zum Antworten