Frage zu Konstruktoren und Klassendesign



  • kurze_frage schrieb:

    das "x > 255 ? 255 : x" koennte natuerlich auch eine Function sein.

    A(int x, int y) 
     : _x (rangeCheckd(x)) , _y (rangeCheckd(y))
        { 
        }
    

    dann schaut es eventuell freundlicher aus

    Ist das nicht ein Problem? Also, Methoden aufzurufen, obwohl das Objekt in der Initialisierungsliste noch nicht vollstaendig konstruiert wurde? Gibt das nicht eventuell undefiniertes Verhalten?

    Wie loest ihr das denn immer? extra-init Funktion? Ueber das neue C11 Feature?



  • Hi,

    Ich haette 3 Fragen.

    1. Was sind x und y wo kommen die Werte her?
    2. Kannst du die Daten nicht vorher validieren?
    3. Du weisst das x und y bei dir theoretisch zwischen -2147483648 und 255 liegen koennen?



  • CppNeuland schrieb:

    Ist das nicht ein Problem? Also, Methoden aufzurufen, obwohl das Objekt in der Initialisierungsliste noch nicht vollstaendig konstruiert wurde? Gibt das nicht eventuell undefiniertes Verhalten?

    Nein, das ist ok.
    Die rangeCheckd-Funktion nutzt ja nichtmal member-Variablen.

    (Vorsicht, Halbwissen):
    Geht auch mit Memberfunktionen, die nur Variablen nutzen, die in der Klassendeklaration vor der zu initialisierenden Variablen stehen.
    Da würde ich allerdings warten, bis das hier einer bestätigt (oder widerlegt).



  • Ruvi schrieb:

    Hi,

    Ich haette 3 Fragen.

    1. Was sind x und y wo kommen die Werte her?
    2. Kannst du die Daten nicht vorher validieren?
    3. Du weisst das x und y bei dir theoretisch zwischen -2147483648 und 255 liegen koennen?

    Das war nur ein konstruiertes Beispiel. Daten die einer Klasse bei der Konstruktion uebergeben werden, sollten meiner Meinung nach in der Klasse selbst auf Gueltigkeit geprueft werden, da jede Klasse fuer ihre Daten selbst verantwortlich sein sollte.

    @Jockelx: Ok, also wenn die check_range Methode wirklich nur diesen Parameter bearbeitet, macht es nix aus. Gut zu wissen.

    P.S.: Es ist wirklich sehr anstrengend hier immer nur ohne Sonderzeichen posten zu koennen.



  • CppNeuland schrieb:

    Das war nur ein konstruiertes Beispiel. Daten die einer Klasse bei der Konstruktion uebergeben werden, sollten meiner Meinung nach in der Klasse selbst auf Gueltigkeit geprueft werden, da jede Klasse fuer ihre Daten selbst verantwortlich sein sollte.

    Edit:
    Also ich persoenlich hatte den Fall den du beschreibst noch nicht.

    Ich persoenlich finde auch, dass der Owner der das Objekt erzeugt dafuer zustaendig ist fuer valide Werte zu sorgen.

    Den Konstruktor auf "gut Glueck" aufzurufen und sich die Werte dann im Notfall hinzuschummeln ist vielleicht nicht so zielfuehrend.

    Mich wuerde schon interessieren wie das andere machen
    .
    Ich persoenlich habe bis jetzt von einer Value "Ueberpruefung" im Konstruktor immer abgesehen denn:

    1. Musst du von irgendwoher erstmal einen nicht validen Wert erhalten.
    2. Musst du auch erstmal in der Lage sein zu erkennen, dass es ein nicht valider Wert ist.
    3. Biegst du den Wert auf etwas anderes um, was im Zweifel trotzdem nicht das ist, was der Nutzer eigentlich wollte bzw. mit dem dein Programm einfach weiterarbeiten kann ohne Folgefehler zu verursachen.

    P.S.:
    Natuerlich ist jede Klasse fuer ihre Daten verantwortlich aber die x und y Werte in deinem Fall kommen nicht von deiner Klasse A.
    An der Stelle wo du die x und y Werte berechnest oder bzw. wem die x und y Werte vorher gehoerten sollte die Validierung stattfinden. (nach meiner Meinung)



  • Unter anderem deswegen wurden doch auch Getter und Setter eingefuehrt, damit man eben nicht einfach den Werten von aussen vertraut wird, sondern damit sie vorher einen Check durchlaufen. Nur wuerde ich ungernen, nach dem erst die Instanz erzeugt wurde, durch Setter meiner Daten in die Members schreiben lassen, sondern dies gleich bei der Generierung machen lassen.



  • CppNeuland schrieb:

    kurze_frage schrieb:

    das "x > 255 ? 255 : x" koennte natuerlich auch eine Function sein.

    A(int x, int y) 
     : _x (rangeCheckd(x)) , _y (rangeCheckd(y))
        { 
        }
    

    dann schaut es eventuell freundlicher aus

    Ist das nicht ein Problem? Also, Methoden aufzurufen, obwohl das Objekt in der Initialisierungsliste noch nicht vollstaendig konstruiert wurde? Gibt das nicht eventuell undefiniertes Verhalten?

    Wie loest ihr das denn immer? extra-init Funktion? Ueber das neue C11 Feature?

    das ist kein Problem, genau genommen ist rangeCheckd sogar eine const expression und sollte daher eigentlich ungefähr so

    template <typename T > constexpr
    T rangeCheckd(T val, T max) { return val > max ? max : val ;}
    
     A(int x, int y) 
     : _x (rangeCheckd(x,255)) , _y (rangeCheckd(y,255))
        { 
        }
    

    aussehen, dann is es auch wiederverwendbarer.

    Syntax Korrektheit kann ich im Moment nicht garantieren da ich das jetzt nur so schnell hingeschrieben hab, aber ich denke das Konzept sollte klar sein.

    edit:
    eigentlich wollt ich rangeCheckd<255>(x) syntax, aber das sample war so falsch das ich es änderte



  • kurze_frage schrieb:

    template <typename T , T max> constexpr
    T rangeCheckd(T val) { return val > max ? max : val ;}
    
     A(int x, int y) 
     : _x (rangeCheckd<255>(x)) , _y (rangeCheckd<255>(y))
        { 
        }
    

    aussehen, dann is es auch wiederverwendbarer.

    lol? Warum max als Template-Argument?



  • crunchexpr schrieb:

    kurze_frage schrieb:

    template <typename T , T max> constexpr
    T rangeCheckd(T val) { return val > max ? max : val ;}
    
     A(int x, int y) 
     : _x (rangeCheckd<255>(x)) , _y (rangeCheckd<255>(y))
        { 
        }
    

    aussehen, dann is es auch wiederverwendbarer.

    lol? Warum max als Template-Argument?

    du warst zu schnell, siehe edit kommentar in meinem post



  • Ist denn das Range-Checken und das finale Verwenden in der Anwendungslogik in der selben Klasse?


Anmelden zum Antworten