Shashin Error:

Invalid data property __get for imageDisplay
Zum Inhalt springen

Archiv

Kategorie: C++

Obwohl es Exceptions im C++ Standard schon etliche Jahre gibt, werden diese in größeren Projekten oft nicht eingesetzt. Im folgenden Artikel möchte ich das Für und Wider erörtern und mit gängigen Vorurteilen aufräumen.

try {
    funktion();
   ...
} catch (const std::invalid_argument& e) {
    std::cerr < < "Falsches Argument:"  << e.what() << std::endl;
} catch (const std::range_error& e) {
    std::cerr << "Ungültiger Bereich:" << e.what() << std::endl;
} catch (...) {
    std::cerr << "Sonstiger Fehler" << std::endl;
}

Gängige Vorurteile

  1. Die Behandlung von Ausnahmen ist codeintensiver (mehr Schreibarbeit)
    Falsch. Ein sinnvolles try/catch braucht ist sogar weniger Code als ein sinnvolles if/else if/elsefür alle möglichen Fehlercodes. Fehlercodes werden aber oft nicht vollständig überprüft oder gar ganz weggelassen, was der Qualität des Codes nicht gerade zuträglich ist. Exceptions dagegen zwingen zu einer durchdachten Fehlerbehandlung.
  2. Exceptions machen den Code langsam
    Falsch. Wenn Exceptions richtig eingesetzt werden, sollten sie für Ausnahmen im Programmablauf verwendet werden. Die Ausführungsgeschwindigkeit des „Gut“-Pfades (in dem keine Ausnahmen geworfen werden) leidet nicht darunter. Wenn also die Exception die Ausnahme und nicht die Regel ist, hat man nichts zu befürchten. weiter lesen…

Ok, ich wollte nur mal eben bei meinem Projekt eine Klasse in ein XML dumpen und wieder einlesen. Hab ich ja mit boost::serialization schon öfter gemacht. Leider hab ich die Klasse aber unter Qt entworfen und daher Basistypen wie QString verwendet. Dieser hat sich allerdings zunächst geweigert…
weiter lesen…

Mit dem C++ Schlüsselwort „explicit“ kann man dem Compiler implizite Typumwandlungen verbieten. Dies kann manchmal ja auch ungewollt passieren, wie folgendes Beispiel zeigt:

#include <iostream>
#include <windows.h>
struct MyClass
{
    MyClass(const char* name) : m_Name(name) {}
    virtual ~MyClass() {}
    const char* Who() const { return m_Name; }
private:
    const char* m_Name;
};
 
struct MyExplicitClass
{
    explicit MyExplicitClass(const char* name) : m_Name(name) {}
    virtual ~MyExplicitClass() {}
 
    const char* Who() const { return m_Name; }
private:
    const char* m_Name;
};
 
 
int main()
{
    MyClass A("a");
    MyExplicitClass B("b");
 
    A = "c";  // ok, hier funktioniert das, aber war das auch so gewollt? 
              // Auf den ersten Blick zu durchschauen ist diese Zuweisung jedenfalls nicht.
 
    B = "d";  // error C2679: Binärer Operator '=': Es konnte kein Operator gefunden werden, 
              // der einen rechtsseitigen Operanden vom Typ 'const char [2]' akzeptiert (oder
              // keine geeignete Konvertierung möglich)
 
    std::cout << "A: " << A.Who() << std::endl;
    std::cout << "B: " << B.Who() << std::endl;
 
    return 0;
}

Eine abstrakte Klasse in C++ hat mindestens eine pure virtual Funktion (gekennzeichnet durch virtual ... = 0). Diese Funktionen können per Definition nicht direkt aufgerufen werden, da sie keine Implementierung haben (auch per Definition). Sollte die Methode dennoch aufgerufen werden, wird das Programm (von der Runtime) mit der Fehlermeldung „Pure virtual function call“ abgebrochen. weiter lesen…

#include <iostream>
 
using namespace std;
 
int main()
{
   cout << "Hi, freaky world!" << endl;
   return 0;
}