2016-04-03 10 views
1

Ich habe eine Klasse wie folgt:Sollte ich eine Ausnahme werfen, einen Fehlercode zurückgeben oder ein Protokoll ausdrucken und abbrechen()?

class MyBuffer 
{ 
    private: 
     char* ptr_; 
    public: 
     MyBuffer(char* ptr_tmp) : ptr_(ptr_tmp) {}; 
     void write_data(int val) 
     { 
      if(ptr_ == NULL) 
      { 
       // What should I do here? 
       // throw an exception, return error code, or just abort()? 
      } 

      // Write val to the buffer pointed by ptr_ 
      // ... 
     } 
}; 

ptr_ nach der Initialisierung nicht geändert werden kann. Das bedeutet, dass die Anweisung ptr_ == NULL nur dann true ist, wenn Entwickler einen NULL-Zeiger im Konstruktor übergeben. Wenn dies der Fall ist, entweder eine Ausnahme auslösen oder einen Fehlercode zurückgeben, sollte der Behandlungscode das Programm TERMINATE sofort beenden.

Ich habe mehrere Diskussionen über Ausnahmen und Fehler gelesen. Es scheint mir, dass eine Ausnahme für "prädiktive", aber "außergewöhnliche" Fälle verwendet werden sollte. In meinem Beispiel, wenn ptr_ == NULL wahr ist, wäre dies keine Ausnahme, sondern ein Bug, oder?

+0

Argumentieren, Sie bei der Initialisierung aus der Patsche helfen soll, wenn ein NULL-Zeiger übergeben, nicht zu einem unbekannten späteren Zeitpunkt. – mustaccio

+0

@mustaccio Wenn ich 'NULL pointer' im Konstruktor überprüft hätte, müsste ich es später überprüfen (z. B. in write_data)? –

Antwort

0

Ein uraltes Dilemma.

Geht es nicht wirklich um Ihr Klassendesign, was ist der Vertrag mit den Verbrauchern?

Wenn write_data() nie nicht schreiben sollte, dann ist eine Ausnahme in Ordnung, außer ich würde es aus dem Konstruktor werfen. Ich möchte immer schnell versagen, sobald Sie wissen, dass der Zeiger ungültig ist, weil write_data niemals funktionieren wird, dann werfen Sie ihn dorthin. Einige Leute sind nicht damit einverstanden, Ausnahmen von einem Konstruktor zu werfen, weil sie eine teilweise instanziierte Klasse hinterlassen können, aber das scheint unbedeutend zu sein. In der tatsächlichen {} überprüfen Sie auf Null und werfen Sie alles, was angemessen ist (in Java würden Sie wahrscheinlich eine InvalidArgumentException werfen).

Sie könnten im Wesentlichen eine verzögerte Initialisierung durchführen, wenn es keine Garantie dafür gibt, dass write_data() tatsächlich aufgerufen wird, und sie daher beim ersten Aufruf der Methode auslösen.

Wenn der Vertrag nicht garantiert, dass etwas in den Puffer geschrieben wird, und ein Nullzeiger daher gültig ist, dann loggen Sie einfach eine Nachricht und fahren Sie fort.

[Ich würde log tatsächlich etwas unabhängig, macht das Debuggen einfacher, wenn die Protokollebene SCHWEREN/FATAL vs. WARNUNG/INFO sein könnte.]