SmartPtr und Null pointer checks



  • Hallo,

    momentan bin ich am überlegen, ob sich für nullpointerchecks ev. smartpointer eignen.

    Das problem ist eben, was mache ich wenn ich einen NULL pointer habe.(*lach* klingt lustig an der Stelle)

    Also in der Form:

    class foo
    {
    public:
     foo():variable(10){}
    
      int variable;
    
    }
    
    ... und dann ...
    foo *bar=0;
    SmartPtr<foo > s_ptr(bar)
    
    // L-Value
    s_ptr->variable = 11;
    // R_Value
    int b=s_ptr->variable;
    

    Wenn ich den operator -> überlade um auf 0 zu prüfen, dann fällt mir nichts anderes ein,außer ein Throw wenn ich einen gefunden habe.

    Geht das auch ohne ??

    Gruß



  • AlexanderKiebler schrieb:

    (*lach* klingt lustig an der Stelle)

    Find ich nicht.

    Warum schreibst du überhaupt eine eigene smart pointer Klasse? Ich würde da keine Exception schmeißen oder so. Genauso wie mit normalen Zeigern muss der Benutzer auch bei smart pointern prüfen, ob er gültig ist.



  • momentan bin ich am überlegen, ob sich für nullpointerchecks ev. smartpointer eignen

    Also bitte beim Thema bleiben. Es geht darum wie man Nullpointer checks mit Smartpointern ohne exceptions programmieren kann.



  • Gar nicht, würde ich sagen. Ein Sonderfall wäre evtl. ein dummy Objekt, das immer alle Methoden von dem richtigen Objekt hat, aber nichts tut. Dann könnte der überladene Operator beim Smart Pointer irgendwie so ausschauen:

    if (obj)
      return obj;
    else
      return dummy;
    

    Sonst würde mir jetzt nichts einfallen. Aber ich denke, null pointer checks sollte man auch nicht verstecken.



  • Hmm ja genau, so ein dummy Teil.....
    Aber schön ist das auch nicht wirklich....

    Wahrscheinlich haste Recht und das läßt sich wirklich nicht so schön mit nem SmartPointer lösen. Werds trotzdem noch etwas weiter versuchen,
    ev.find ich ja noch net tolle Lösung.



  • Warum sollte man ein besonderes Verhalten für den Fall definieren, wo operator-> auf einem Nullzeiger angewandt wird? Das ist ein Logikfehler, den sollte man möglichst schnell elimieren und sicher nicht verstecken.

    AlexanderKiebler schrieb:

    Das problem ist eben, was mache ich wenn ich einen NULL pointer habe

    Den Bug fixen. Nullzeiger haben nicht dereferenziert zu werden.

    (Übrigens: "fixen" heisst meist nicht, jede Dereferenzierung mit einem if zu "schützen", sondern gar nicht erst Nullzeiger zu haben. Siehe auch hier).



  • AlexanderKiebler schrieb:

    Es geht darum wie man Nullpointer checks mit Smartpointern ohne exceptions programmieren kann.

    assert



  • Hmm das Problemist, dass unsre Software auch mit Null pointer weiter laufen muss, um fehler zu reporten.

    Also Assert kommt für mich nicht in Frage.



  • AlexanderKiebler schrieb:

    Hmm das Problemist, dass unsre Software auch mit Null pointer weiter laufen muss, um fehler zu reporten.

    Dann mach das doch einfach.

    if (ptr)
    {
    	ptr->machen();
    }
    else
    {
    	//Fehlerbehandlung
    }
    


  • Das problem ist finde ich,
    dass eine Funktion

    void set_a(int error)
    {
    if(ptr)
    ptr->mache_einen_Teil_von_a();
    else
    //Melde fehler
    }
    

    viel Wissen hat.
    Mir wäre es lieber wenn die Funktion set_a auch nur das macht was sie soll,
    und sich nicht auch noch um Pointer kümmern muss.
    Das ist nicht ihre Aufgabe.

    Also würde ich mich dafür entschließen, die Pointerchecks mit einer Funktion zu prüfen:

    z.B.

    check_ptr()
    {
     prüfe alle pointer
    }
    
    // und dann später
    void set_a(int error)
    {
    
    ptr->mache_einen_Teil_von_a();
    
    }
    

    Ich finde man muss das trennen und man sollte einer Funktion eindeutig eine Aufgabe zuordnen können.

    Am schönsten wäre es, wenn sich der Teil des Codes, welcher für die Fehlerbehandlung zuständig ist durch die SmartPointer automatisch mitschreibt,
    ohne dass man sich darum kümmern muss...
    Dann kann man sich beim programmieren einer Funktion auch auf deren Aufgabe fokusieren.



  • Deshalb darf set_a einfach nie einen Nullzeiger bekommen.

    Du versteckst damit nur Programmierfehler. Das kann man zwar machen, aber das macht den Code deshalb nicht robuster - sondern nur schwerer zu debuggen.



  • Na ja ich finde der Code würde damit übersichtlicher werden.
    Dabei sind normalerwiese die Nullpointer nach geraumer Zeit für ein Modul draussen. (Nach meiner erfahrung)

    Und ab dem Zeitpunkt glaube ich wirklich dass man sich ev. besser auf die set_a funktion konzentrieren kann.

    Vorallem könnet man dem SmartPointer ne Policy mitgeben welche pointer checkt, und eine welche sie wie ein raw pointer verhält.

    Wenn dann nach dem Überschreiten eines gewissen Entwicklugsstadiums alle Null pointer draussen sind, könnte man wieder raw Pointer verwenden, und auf die Nullpointer checks generell verzichten.

    Oder ne Pollicy mit einer Art CRC vor jedem dereferenzieren gegen bit kipper =)...
    (Eine die das Problem nicht schlimmer macht)



  • AlexanderKiebler schrieb:

    Dabei sind normalerwiese die Nullpointer nach geraumer Zeit für ein Modul draussen. (Nach meiner erfahrung)

    Die vernünftige Lösung für das Problem ist, einfach keine Nullzeiger zu erzeugen.
    Mit OOP und ein wenig Hirnschmalz kann man Programme entwickeln, die fast ohne Nullzustände auskommen.
    Faustregel: Wenn derselbe Zeiger an mehreren Stellen auf Null geprüft wird, macht man etwas falsch.



  • Ich bin auch für einen Assert. Wenn das Programm bei euch im Debug modus beendet wird, dann findet ihr den Fehler sofort und könnt ihn beheben. Wenn der Kunde im Release modus einen Nullpointer kriegt, dan hilft euch das gar nichts.

    Programmeirt einfach so, dass niemals Nullpointer auftreten und behandelt ihr auftreten als schlimmstmöglichen Fehler.



  • Wieso Nullzeiger nicht sofort dann behandeln wenn sie auftreten?
    Also soetwas:

    std::unique_ptr<Widget> widget(createWidget());
    if(!widget)
        throw std::runtime_error("Could not create widget !");
    


  • Ethon_ schrieb:

    Wieso Nullzeiger nicht sofort dann behandeln wenn sie auftreten?
    Also soetwas:

    std::unique_ptr<Widget> widget(createWidget());
    if(!widget)
        throw std::runtime_error("Could not create widget !");
    

    Da steckt die Lösung drin. EIn Smartpointer soll sich weitesgehend verhalten, wie ein normaler Zeiger. Das bedeutet auch, dass der Benutzer eines Smartpointer-Objekts nicht wissen kann, ob dieser auf etwas gültiegs Zeigt. Dementsrechend muss der Benutzer, sofern der Zeiger im Kontext potentiell null sein kann, auch selbst prüfen, ob dieser null ist.


Anmelden zum Antworten