Methoden mit bool-Parametern und "Lesbarkeit" im Kontext



  • ulfbulf schrieb:

    ach ne moment sind ja eh alles kiddies hier also schnauze cstoll shade etc. 🤡 😋

    Sagt wer? Wenn du uns beleidigen willst, dann bitte mit Namen und Anschrift.



  • CStoll schrieb:

    ulfbulf schrieb:

    ach ne moment sind ja eh alles kiddies hier also schnauze cstoll shade etc. 🤡 😋

    Sagt wer? Wenn du uns beleidigen willst, dann bitte mit Namen und Anschrift.

    merkst du nix 😕 🙄



  • CStoll schrieb:

    Nehmen wir nochmal als Kontrast das Auto-Beispiel - ein Auto HAT eine Farbe, aber IST (bestenfalls) ein färbbares Objekt. Genauso würde ich, wenn ich Vererbung nutzen wollte, eine Basisklasse Flagable verwenden, die Methoden SetFlag(), ResetFlag() und CheckFlag() anbietet (eventuell auch als Template).

    Ach ich weis nicht. Da die Operatoren ja nicht virtual sind und es im Grunde nichts vererbt wird, find ich das nicht so wichtig. Ist mehr ein Syntax-Sucker und hat weniger mit der OOA zu tun.

    CStoll schrieb:

    technisch möglich, aber so hast du eine Mehrdeutigkeit, weil Window zwei MeineFlags-Subobjekte hat (einmal direkt und einmal indirekt in MeineErweiterten Flags).

    Spielst eine Rolle, da die Flag-Klassen keine Felder und keine Methoden haben und von niemanden erstellt werden?
    Btw, von den einzelnen Flag-Klassen spezielle Flag-Klassen abzuleiten macht ja auch kein Sinn.

    Ich sehe in der Methode eher Vorteile:
    - Der Compiler entscheidet, wohin ein Flag genau gespeichert wird. Ich kriege eine groessere Transparenz, da ich einfach dem Objekt bestimmte Eigenschaften zuweisen kann, ohne spezielle Methoden ansprechen zu muessen.

    object = EigenschaftX;
    if ( object & EigenschaftX ) { /*...*/ }
    

    Die interne Implementation bleibt mir dabei verborgen, und das ist immer ein Vorteil.
    - Man hat Typsicherheit bei den Flags.
    - Ausserdem ist es eine kuerzere Schreibweise.



  • DEvent schrieb:

    CStoll schrieb:

    Nehmen wir nochmal als Kontrast das Auto-Beispiel - ein Auto HAT eine Farbe, aber IST (bestenfalls) ein färbbares Objekt. Genauso würde ich, wenn ich Vererbung nutzen wollte, eine Basisklasse Flagable verwenden, die Methoden SetFlag(), ResetFlag() und CheckFlag() anbietet (eventuell auch als Template).

    Ach ich weis nicht. Da die Operatoren ja nicht virtual sind und es im Grunde nichts vererbt wird, find ich das nicht so wichtig. Ist mehr ein Syntax-Sucker und hat weniger mit der OOA zu tun.

    Und mir ist die Flag-Klasse halt zu sehr übersüsst 😃

    CStoll schrieb:

    technisch möglich, aber so hast du eine Mehrdeutigkeit, weil Window zwei MeineFlags-Subobjekte hat (einmal direkt und einmal indirekt in MeineErweiterten Flags).

    Spielst eine Rolle, da die Flag-Klassen keine Felder und keine Methoden haben und von niemanden erstellt werden?
    Btw, von den einzelnen Flag-Klassen spezielle Flag-Klassen abzuleiten macht ja auch kein Sinn.

    Erstens hat die Flag-Klasse Datenmember (ihr Wert) und Methoden (die Flag-Operatoren) und zweitens tritt die Merhdeutigkeit schon dadurch auf, daß Window nicht mehr eindeutig zu einem Flag reduziert werden kann (das ist wichtig, um den Aufruf 'wnd&MeineFlags::Flag1' auflösen zu können).

    Ich sehe in der Methode eher Vorteile:

    Und ich sehe auch die Nachteile:
    - unintuitive Verwendung ( object=Eigenschaft ist zwar schön zu schreiben, aber der Anwender muß erstmal darauf kommen, was sich hinter dieser Zuweisung verbirgt)
    - Aufwand bei der Erweiterung (op& wird vererbt, wobei ich mir nicht ganz sicher bin, welche Operatoren der Compiler überhaupt in die Überladungsauflösung einbeziehen darf, op= muß die abgeleitete Klasse selber übernehmen (und das im Zweifelsfall für alle Flag-Klassen, die unterwegs aufgesammelt wurden).

    PS: Und Typsicherheit kann man auch auf anderem Weg erreichen 😉

    Edit @ulf: Ich merke, daß du ein Troll bist



  • CStoll schrieb:

    Edit @ulf: Ich merke, daß du ein Troll bist

    macht nix, vielleicht gibts in diesem foru ja doch noch andere leute die ironie verstehen 👍



  • Wir waren gerade dabei, eine schöne konstruktive Diskussion aufzubauen. Das mußt du jetzt nicht kaputtmachen, indem du versuchst, plumpe (und sinnlose) Zwischenbemerkungen zu machen - und nachträglich als "Ironie" zu deklarieren. Wenn du also nichts konstruktives beitragen kannst, dann halt lieber Abstand.



  • is ja gut is ja gut, wenn du die anspielung nicht verstehst ignorier sie halt einfach 🙄



  • DEvent schrieb:

    Ich sehe in der Methode eher Vorteile:
    - Der Compiler entscheidet, wohin ein Flag genau gespeichert wird. Ich kriege eine groessere Transparenz, da ich einfach dem Objekt bestimmte Eigenschaften zuweisen kann, ohne spezielle Methoden ansprechen zu muessen.

    object = EigenschaftX;
    if ( object & EigenschaftX ) { /*...*/ }
    

    Die interne Implementation bleibt mir dabei verborgen, und das ist immer ein Vorteil.

    Nein, das ist ein Trugschluss.
    Sag mir einfach ob folgender Code korrekt ist:

    window = Fullscreen;
    window = Border3D;
    

    Niemand kann es sagen. Ist Fullscreen und Border3D vom selben Flag-Typ? Wenn ja: böser Fehler, wenn nein dann funktioniert es.
    Es kompiliert anstandslos. egal was nun der Fall ist. Gefährliches Problem.

    Kann einem bei

    window.Mode = Fullscreen;
    window.DialogMode = Border3D;
    

    nicht passieren. Natürlich kann man außerhalb der Klasse ein Window::Fullscreen und Dialog::Fullscreen nutzen um so die wahrscheinlichkeit eines fehlers zu reduzieren - aber er ist gegeben und wahnsinnig schwer auffindbar. Und man muss sehr wohl wissen was ein Dialog Mode und was ein Window Mode ist - da ist nichts mit Transparenz. Genausowenig wie bei window.Mode und window.DialogMode.

    - Man hat Typsicherheit bei den Flags.

    Hat man ohne vererbung genauso.

    - Ausserdem ist es eine kuerzere Schreibweise.

    sobald das als argument genannt wird, sollten alle alarmglocken läuten.

    schreibfaulheit ist nie ein guter grund.

    Wir haben die Vorteile also auf genausoviele wie die window.Mode/window.DialogMode syntax reduziert.

    Dazu die Nachteile:
    total verwirrende Syntax und eigentlich genau ein Beispiel dafür warum manche Leute operator overloading verbieten wollen. operatoren werden umdefiniert und den ursprüngliche sinn wird nicht erhalten:

    window = a;
    window = b;
    
    &a == &b //false
    &window == &a //true
    

    das verwirrt jeden leser erstmal gehörig. es ist nämlich ein absolut unnatürliches verhalten.

    davon dass window keine flags ist sondern hat - ok, wir wissen ja wie verkorkst hier manche leute OOP sehen 😉

    Jede neue Flag-Klasse macht den Code noch mehr komplex. Mit 1 Klasse ist es nett, mit 2 ist es komisch und wird immer schlimmer je mehr Klassen dazu kommen.

    Es gibt abstruse fehlerquellen, wie zB eine Funktion die die Flags auslesen will: die bekommt dann gleich das ganze window-objekt. window & dialog ist ebenfalls ein abstruses problem.

    Die Frage ist: welchen Vorteil bringt vererbung dann hier? Ganz einfach: vererbung wird hier eingesetzt um schreibarbeit zu reduzieren. das ist der ganze vorteil dieser syntax - mehr nicht. wer dafür unlesbaren code produzieren will: bitte. aber dann sollte man auch sagen warum man es so macht und nicht irgendwelche komischen gründe finden warum diese syntax besser ist.



  • Shade Of Mine schrieb:

    Xin schrieb:

    Shade Of Mine schrieb:

    Wenn ich nun so dumm bin und die Flags von Windows und Dialog so trenne - dann habe ich das selbe Problem mit der "eleganten Syntax". Wenn Modal ein Flag von Dialog ist und Fullscreen einer von Dialog, dann ist sowas schon ziemlich dirty zu implementieren:

    win = Model | Fullscreen;
    

    natürlich möglich - aber dann wird die implementierung langsam häßlich.

    Sorry, das ist nicht möglich, da operator | ( WindowFlags &, DialogFlags & ) nicht definiert ist.

    Und genau das sind die Punkte die einen Anwender verwirren.

    Wenn ich

    win = Fullscreen;
    win = Modal;
    

    machen kann...

    Auch auf die Gewissheit hin, dass ich mich wiederhole: Es geht nicht...

    Shade Of Mine schrieb:

    man trennt die beiden Flags nicht also will ich eigentlich:

    win = Fullscreen | Modal;
    

    machen.

    Auch auf die Gewissheit hin, dass ich mich wiederhole: Es geht nicht...

    Warum antworte ich Deine Postings, wenn Du sie nicht liest!?

    Shade Of Mine schrieb:

    Aber auch dieser Beitrag geht nicht an Xin, sondern an etwaige leser.

    Und was sollen die damit anfangen!? Du kritisierst Dinge, die so nicht gehen, ergo auch nicht kritisiert werden können.

    Der einzige, der hier Leute verwirrt, bist Du, denn...

    DEvent schrieb:

    win = Fullscreen | Modal;
    

    Sowas waere echt cool, wenns denn moeglich waere...

    Auch auf die Gewissheit hin, dass ich mich wiederhole: Es geht nicht...
    DEvent, das wäre auch nicht cool, denn die Intention wäre hier nicht verwandte Datenobjete mit | zu verbinden. Und weil sie nicht verwandt sind, geht das auch nicht, also lass Dir von Shade keinen Unsinn einreden. Was Shade schreibt, hat nichts mit meinen Flag-Klassen zu tun, sondern mit Enums und genau die verwende ich nicht.

    Edit: Da Shade immernoch falschen Code verbreitet hier nochmal der richtige:

    win = WindowFlags::FullScreen;     // WindowFlags & WindowFlags::operator = ( WindowFlags const & ) - gibt's => geht
    win = WindowMode::Modal;           // WindowMode  & WindowMode ::operator = ( WindowMode  const & ) - gibt's => geht
    

    Zwei nicht verwandte Typen, die Shade hier mit | verbindet:

    win = WindowFlags::FullScreen | WindowMode::Modal; //  ??? & operator ???::operator | ( WindowFlags & const, WindowMode const & )  - Gibt's nicht => geht nicht
    

    Und nochmal: Du musst angeben, welchen Typ der Flag hat, darum ist es eindeutig. Ohne Typ, kein Flag. Darum hat der Code von Shade nichts mit meinen Flagklassen zu tun.

    CStoll schrieb:

    Xin schrieb:

    CStoll schrieb:

    Es gibt kein Chaos, da Window sich genauso verhält, als wäre es mit Window::Flags implementiert worden.

    Du hast mir immer noch nicht verraten, was der Ausdruck 'wnd1&wnd2' für eine Bedeutung haben soll.

    Wenn operator & für zwei Fenster nicht deklariert ist, würde eine Hirachie hochgegangen und das Ergebnis wären übereinstimmende WindowFlags, genauso wie wnd1->Flags & wnd2->Flags.
    Wenn Dir das nicht gefällt, deklariere operator & als private member.

    Ist dir klar, daß du dadurch auch die (normal erlaubten) Aufrufe wie 'w&Window::FullScreen' wieder außer Gefecht setzt?

    Nopes, ist mir nicht klar.
    operator & ( Window &, Window & ) fängt w&d ab, aber nicht w & WindowFlag::FullScreen.

    CStoll schrieb:

    Und dafür benötigt die Window-Klasse dann ein halbes Dutzend Zuweisungsoperatoren (und je tiefer du in die Hierarchie runtersteigst, desto mehr werden es ;)).

    Und? Sind alle eindeutig, werden vererbt und es gibt keine tausenden von Funktionen.

    CStoll schrieb:

    Allerdings mal eine Frage, ist sowas moeglich:

    class MeineFlags { }
    
    class MeineErweitertenFlags : MeineFlags { }
    
    class Window : public MeineFlags, MeineErweitertenFlags {}
    

    Also kann ich MeineFlags erweitern, indem ich davon ableite? Muesste eigentlich gehen?

    technisch möglich, aber so hast du eine Mehrdeutigkeit, weil Window zwei MeineFlags-Subobjekte hat (einmal direkt und einmal indirekt in MeineErweiterten Flags).

    PS: Gut zu wissen, daß ich nicht alleine dastehe.

    Man muss schon wissen, was man tut und dass die Flags nicht in einer Vererbungslinie stehen dürfen, weil sie sonst doppelt auftreten, ist wohl klar. Darum Templates, damit man eben nicht eine Vererbungslinie aufbaut.

    ulfbulf schrieb:

    eine Window klasse von einer WIndowFlags klasse abzuleiten macht keinen sinn 👎
    ach ne moment sind ja eh alles kiddies hier also schnauze cstoll shade etc. 🤡 😋

    Solange Du nicht Mann genug bist, mit einer erkennbaren Identität gegen mich zu trollen, so troll dich. Kritik gegenüber bin ich offen, derartige Pöpeleien machen aus dem Forum einen Kindergarten. Also werd erwachsen.
    Solltest Du derjenige IRC-Admin sein, der mich im #cpp mit der Begründung gebannt hat, weil er mich im Forum nicht mag und mich nicht aus dem Forum werfen kann, dann kann ich Dir nur sagen: Die Pubertät sollte mit 20 langsam abgeschlossen sein.



  • Shade Of Mine schrieb:

    Sag mir einfach ob folgender Code korrekt ist:

    window = Fullscreen;
    window = Border3D;
    

    Niemand kann es sagen. Ist Fullscreen und Border3D vom selben Flag-Typ? Wenn ja: böser Fehler, wenn nein dann funktioniert es.
    Es kompiliert anstandslos. egal was nun der Fall ist. Gefährliches Problem.

    Es kompiliert nicht, warum der Code eindeutig falsch ist, steht im Posting zuvor.

    Shade Of Mine schrieb:

    window = a;
    window = b;
    
    &a == &b //false
    &window == &a //true
    

    das verwirrt jeden leser erstmal gehörig. es ist nämlich ein absolut unnatürliches verhalten.

    Das Zweite ist false.

    Shade Of Mine schrieb:

    - Ausserdem ist es eine kuerzere Schreibweise.

    sobald das als argument genannt wird, sollten alle alarmglocken läuten.

    schreibfaulheit ist nie ein guter grund.

    Schreibfaulheit ist in Algorithmen ein sehr guter Grund, weil je weniger Blah-Text, desto mehr kann man sich auf den Algorithmus konzentrieren. Dafür nehme ich in Kauf, dass die Erstellung der Flags aufwendiger(!) ist.
    Schreibfaulheit selbst ist also nicht das Ziel der Flag-Klassen.

    Shade Of Mine schrieb:

    davon dass window keine flags ist sondern hat - ok, wir wissen ja wie verkorkst hier manche leute OOP sehen 😉

    Und wir wissen, dass manche Leute, andererleuts Postings nicht lesen oder nicht verstehen. 😉

    Dir gefällt die Idee nicht, das ist okay.
    Die Idee scheint mir von Dir noch nicht ganz verstanden zu sein. Es steht Dir frei das ganze mal auszuprobieren und auszutesten und es steht Dir auch frei dagegen zu sein. Deine Argumentation haben aber nichts mit den Flag-Klassen zu tun.



  • Xin schrieb:

    Auch auf die Gewissheit hin, dass ich mich wiederhole: Es geht nicht...

    Warum antworte ich Deine Postings, wenn Du sie nicht liest!?

    Alle meine Beispiele gehen sehr wohl - nicht immer 1:1 auf deinen Beispielcode bezogen, aber da du sowieso keinen kompletten Code gepostest hast ist sowas kaum zu vermeiden.

    DEvent schrieb:

    win = Fullscreen | Modal;
    

    Sowas waere echt cool, wenns denn moeglich waere...

    Auch auf die Gewissheit hin, dass ich mich wiederhole: Es geht nicht...

    Und auch das ist problemlos möglich.

    Nicht immer ist dein Code das einzig mögliche. Wenn man ein win = Fullscreen | Modal will, dann kann man es machen. Technisch absolut kein Problem. Aber es geht hier nicht um Technik.

    Edit: Da Shade immernoch falschen Code verbreitet hier nochmal der richtige:

    win = WindowFlags::FullScreen;     // WindowFlags & WindowFlags::operator = ( WindowFlags const & ) - gibt's => geht
    win = WindowMode::Modal;           // WindowMode  & WindowMode ::operator = ( WindowMode  const & ) - gibt's => geht
    

    Auch wenn es dich schockiert - ob man nun WindowFlags/WindowMode oder sonstwas qualifiziert - es bleibt ein a=b für den Leser.

    Zwei nicht verwandte Typen, die Shade hier mit | verbindet:

    win = WindowFlags::FullScreen | WindowMode::Modal; //  ??? & operator ???::operator | ( WindowFlags & const, WindowMode const & )  - Gibt's nicht => geht nicht
    

    Ich sehe 0 Probleme sowas technisch zu implementieren.

    Und nochmal: Du musst angeben, welchen Typ der Flag hat, darum ist es eindeutig. Ohne Typ, kein Flag. Darum hat der Code von Shade nichts mit meinen Flagklassen zu tun.

    Ob ich qualifiziere oder nicht ändert den Code kein bisschen. Mal abgesehen davon dass ich nicht immer qualifizieren _muss_ - zB in der Window Klasse drinnen.

    Wenn operator & für zwei Fenster nicht deklariert ist, würde eine Hirachie hochgegangen und das Ergebnis wären übereinstimmende WindowFlags, genauso wie wnd1->Flags & wnd2->Flags.
    Wenn Dir das nicht gefällt, deklariere operator & als private member.

    Mehr Code komplexität.

    Shade Of Mine schrieb:

    window = a;
    window = b;
    
    &a == &b //false
    &window == &a //true
    

    das verwirrt jeden leser erstmal gehörig. es ist nämlich ein absolut unnatürliches verhalten.

    Das Zweite ist false.

    Ja, mein Fehler. Die & muss man sich wegdenken, ich habe etwas daran herumgebastelt und da ist der Fehler reingerutscht.

    Da b ein Flag ist und somit keine Zuweisung stattfindet, auch wenn da ein op= war, führt das zu schwer zu verstehenden Code.

    Schreibfaulheit ist in Algorithmen ein sehr guter Grund, weil je weniger Blah-Text, desto mehr kann man sich auf den Algorithmus konzentrieren. Dafür nehme ich in Kauf, dass die Erstellung der Flags aufwendiger(!) ist.
    Schreibfaulheit selbst ist also nicht das Ziel der Flag-Klassen.

    Zeig mal bitte ein Beispiel wo Schreibfaulheit besser ist als sinnvolle Namen und Konventionen. Man verwendet deshalb ja auch "sort" und nicht "s" 😉
    Man hat vector<int>::iterator statt einen vector der sich wie ein iterator verhält 😉

    Und wir wissen, dass manche Leute, andererleuts Postings nicht lesen oder nicht verstehen. 😉

    Und manche Leute wollen nicht verstehen. Ja, das wissen wir.

    Dir gefällt die Idee nicht, das ist okay.
    Die Idee scheint mir von Dir noch nicht ganz verstanden zu sein. Es steht Dir frei das ganze mal auszuprobieren und auszutesten und es steht Dir auch frei dagegen zu sein. Deine Argumentation haben aber nichts mit den Flag-Klassen zu tun.

    Du ignorierst ja - genau wie bei der OOP Diskussion die Punkte die dir nicht gefallen.

    Ich habe die Idee durchaus verstanden - es erinnert mich an den Stack in Java. Erspart Schreibarbeit aber das war es auch schon.

    Auch wenn du es wieder ignorieren wirst:
    nenn mir mal die Vorteile von deiner Methode gegenüber nicht vererben.

    Schreibarbeit ist der einzige Vorteil. Es kann keinen anderen geben als Syntax weil es technisch gleichwertig mit "w->Mode" ist.

    Und genau diese Syntax kritisiere ich - auch wenn du die Kritik ignorierst. Das ist mir egal. Ich will nur nicht dass Leute wie DEvent dann prompt auf sowas "reinfallen" und nur die ersparte Schreibarbeit sehen.

    Es gibt eine Menge pitfalls die man beachten muss damit dein Code korrekt läuft. zB w&d ist etwas dass man sehr sehr leicht übersehen kann.

    Dazu eben die von mir genannten logischen Probleme die ich genannt habe.

    Mir ist durchaus klar wie praktisch diese ersparte Schreibarbeit ist. Aber da ersparte schreibarbeit das unwichtigste von allen Punkten ist, zieht das bei mir nicht so. Ich sehe vielmehr die ganzen Probleme, die ich ohne vererbung nicht hätte.

    PS:

    if(win) {
    }
    

    was genau macht das eigentlich?
    testet es ob das fenster in einem guten zustand ist? oder ist es der test auf flags?

    lässt sich alles natürlich definieren - aber wo bleibt die intuition?



  • Shade Of Mine schrieb:

    was genau macht das eigentlich?
    testet es ob das fenster in einem guten zustand ist? oder ist es der test auf flags?

    lässt sich alles natürlich definieren - aber wo bleibt die intuition?

    Intuition in C++ Operatorueberladung? Es ist genauso eine Gewoehnung wie in dem unterem Beispielcode, da sehe ich keinen Unterschied.

    std::string b = "b";
    std::string c = "c";
    std::string a = b + c;
    std::string a = b - c; // ???
    

    Xin hat eigentlich sehr wohl einen Code gepostet, gleich auf Seite 1, die MyClassFlags Klasse.

    Xin schrieb:

    Auch auf die Gewissheit hin, dass ich mich wiederhole: Es geht nicht...
    DEvent, das wäre auch nicht cool, denn die Intention wäre hier nicht verwandte Datenobjete mit | zu verbinden. Und weil sie nicht verwandt sind, geht das auch nicht, also lass Dir von Shade keinen Unsinn einreden. Was Shade schreibt, hat nichts mit meinen Flag-Klassen zu tun, sondern mit Enums und genau die verwende ich nicht.

    Ich meinte eigentlich das Fullscreen und Modal beide Flags sind. Sowas muesste doch gehen. Das man nicht verschiedene Typen miteinander mischen kann, ist logisch.

    window = WindowFlags::Fullscreen | WindowFlags::Modal.
    

    Xin schrieb:

    Man muss schon wissen, was man tut und dass die Flags nicht in einer Vererbungslinie stehen dürfen, weil sie sonst doppelt auftreten, ist wohl klar. Darum Templates, damit man eben nicht eine Vererbungslinie aufbaut.

    Man kann die FlagKlassen aber nicht final/sealed machen? Sonst geht das untere ja nicht. Das ist aber schlecht: Darf zwar von den Flag-Klassen keine speziellen Extended-Flag-Klassen machen, kann aber diese Flag-Klassen nicht gegen Vererbung schuetzen.

    class Window : public FlagClass { }
    

    Also was geht alles:

    window = Flags::Fullscreen; // weist dem Window den Flag Fullscreen zu
    window = Flags::Modal; // weist dem Window den Flag Modal zu
    window = Flags::Fullscreen | Flags::Modal; // weist dem Window beide Flags zu?
    if ( window & Flags::Fullscreen ) // testet, ob Window den Flag Fullscreen hat
    window = window2; // ??
    if ( window & window2 ) // ??
    if ( window ) // ??
    


  • Shade Of Mine schrieb:

    DEvent schrieb:

    win = Fullscreen | Modal;
    

    Sowas waere echt cool, wenns denn moeglich waere...

    Auch auf die Gewissheit hin, dass ich mich wiederhole: Es geht nicht...

    Und auch das ist problemlos möglich.

    Nicht immer ist dein Code das einzig mögliche. Wenn man ein win = Fullscreen | Modal will, dann kann man es machen. Technisch absolut kein Problem.

    Technisch kein Problem. Aber es ist nicht das, was ich vorgeschlagen habe.
    Mit meinem Vorschlag musst Du an den interessanten Punkten Qualifizieren und bei Deinem Befehl wird mit einer Fehlermeldung die Kompilierung verweigert.
    Dann kannst Du nicht etwas anderes schreiben, dann hingehen und mir sagen, dass das Geänderte gegen mein Vorgehen spricht. Man kann vieles machen, aber was Du kritisierst, habe ich nicht gemacht und mein Vorgehen erlaubt es auch nicht.

    Shade Of Mine schrieb:

    Edit: Da Shade immernoch falschen Code verbreitet hier nochmal der richtige:

    win = WindowFlags::FullScreen;     // WindowFlags & WindowFlags::operator = ( WindowFlags const & ) - gibt's => geht
    win = WindowMode::Modal;           // WindowMode  & WindowMode ::operator = ( WindowMode  const & ) - gibt's => geht
    

    Auch wenn es dich schockiert - ob man nun WindowFlags/WindowMode oder sonstwas qualifiziert - es bleibt ein a=b für den Leser.

    Das schockt mich nicht und was Du sagst ist korrekt. Die Qualifizierung sagt aber klar aus, welcher Part durch die Zuweisung betroffen ist.

    Das ist natürlich eine Konvention. Ob einem das gefällt oder nicht ist eine subjektive Geschichte. Als Lösung funktioniert es.

    Shade Of Mine schrieb:

    Zwei nicht verwandte Typen, die Shade hier mit | verbindet:

    win = WindowFlags::FullScreen | WindowMode::Modal; //  ??? & operator ???::operator | ( WindowFlags & const, WindowMode const & )  - Gibt's nicht => geht nicht
    

    Ich sehe 0 Probleme sowas technisch zu implementieren.

    Ich sehe auch kein Problem es zu implementieren.
    Was aber nichts daran ändert, dass ich es weder tat, noch propagierte.
    Anders ausgedrückt: Was hat das mit meinem Vorgehen zu tun?!

    Shade Of Mine schrieb:

    Und nochmal: Du musst angeben, welchen Typ der Flag hat, darum ist es eindeutig. Ohne Typ, kein Flag. Darum hat der Code von Shade nichts mit meinen Flagklassen zu tun.

    Ob ich qualifiziere oder nicht ändert den Code kein bisschen. Mal abgesehen davon dass ich nicht immer qualifizieren _muss_ - zB in der Window Klasse drinnen.

    Es ändert die Lesbarkeit des Codes.

    Das Ziel der Sache ist die Handhabung mit der Window-Klasse (bzw. der Klasse, die zu flaggen ist) zu optimieren und das wird erreicht. Die Windowklasse selbst muss in C++ diszipliniert entwickelt werden. Es muss immer diszipliniert entwickelt werden. Die Windowklasse wird vom "Profi" entworfen, der die Klasse kennt, schließlich entwickelt er sie ja - die Verwendung mit dem Flags sichert dem Unerfahreneren den sicheren Umgang mit der Klasse. Das ist der Punkt.

    Flags sind so alltäglich, dass sie auch standardisiert verwendet werden sollten. C++ bietet keine sprachgestützte Verwendung von Flags. Darum baue ich die Flagklassen.

    Wenn ich eine geflaggte Klasse entwickelt habe, muss ich nicht mehr groß nachdenken, um damit zu arbeiten, oder mir den Namen der Variablen für die Flags raussuchen, wenn ich etwas verkehrt mache meckert der Compiler. Die Flagklasse erhöht meine Produktivität mehr, als mich das Schreiben der Flagklasse ausbremst.

    Das muss auf andere deswegen nicht zwangsläufig zutreffen, ich halte es jedoch für begründet, dass es anderen ebenso gehen kann.

    Shade Of Mine schrieb:

    Shade Of Mine schrieb:

    window = a;
    window = b;
    
    &a == &b //false
    &window == &a //true
    

    das verwirrt jeden leser erstmal gehörig. es ist nämlich ein absolut unnatürliches verhalten.

    Das Zweite ist false.

    Ja, mein Fehler. Die & muss man sich wegdenken, ich habe etwas daran herumgebastelt und da ist der Fehler reingerutscht.

    Da b ein Flag ist und somit keine Zuweisung stattfindet, auch wenn da ein op= war, führt das zu schwer zu verstehenden Code.

    Das ist die Frage nach den Konventionen. Es gibt kein Argument dagegen, wenn Du den Code als schwerer zu verstehen empfindest. Ich habe mich damit mehr beschäftigt, von daher ist was mir offensichtlich ist, einem anderen Leser vielleicht befremdlich.
    Einem Leser, der das Verhalten in einem Framework immer wieder findet, wird sich schnell an das Verfahren gewöhnen.

    Shade Of Mine schrieb:

    Schreibfaulheit ist in Algorithmen ein sehr guter Grund, weil je weniger Blah-Text, desto mehr kann man sich auf den Algorithmus konzentrieren. Dafür nehme ich in Kauf, dass die Erstellung der Flags aufwendiger(!) ist.
    Schreibfaulheit selbst ist also nicht das Ziel der Flag-Klassen.

    Zeig mal bitte ein Beispiel wo Schreibfaulheit besser ist als sinnvolle Namen und Konventionen. Man verwendet deshalb ja auch "sort" und nicht "s" 😉
    Man hat vector<int>::iterator statt einen vector der sich wie ein iterator verhält 😉

    Hinter das "sort" wie "s" setzt Du direkt das Smiley, und dass ein Vector keine 1:1 Beziehung zu Iteratoren hat, wie es bei Window und WindowFlags der Fall ist, ist wohl offensichtlich. Auch hier setzt Du direkt ein Smiley hinter.
    Also verstehe ich die Frage nicht.

    Schreibfaulheit ist eine subjektive Sache.

    Ich mag kein Pascal, weil ich keine Romane schreiben will. Ich empfinde { und } als Vorteil zu begin und end, weil ich die Klammern optisch besser von den Worten trennen kann. Hier sehe ich Schreibfaulheit als Vorteil.
    Bei Template-Templates sehe ich den Vorteil ein typedef oder eine entsprechende Class abzuleiten, statt mir mit endlosen Datentyp-Namen einen Wolf zu schreiben, was keiner mehr durchblickt.

    Mein Vorgehen bietet sinnvolle Namen und Konventionen. Ich muss mich also nicht gegen eins entscheiden.
    Auf dieser Ebene verstehe ich die Frage auch nicht.

    [quote="Shade Of Mine"]

    [quote="Shade Of Mine"]

    Und wir wissen, dass manche Leute, andererleuts Postings nicht lesen oder nicht verstehen. 😉

    Und manche Leute wollen nicht verstehen. Ja, das wissen wir.

    Dir gefällt die Idee nicht, das ist okay.
    Die Idee scheint mir von Dir noch nicht ganz verstanden zu sein. Es steht Dir frei das ganze mal auszuprobieren und auszutesten und es steht Dir auch frei dagegen zu sein. Deine Argumentation haben aber nichts mit den Flag-Klassen zu tun.

    Du ignorierst ja - genau wie bei der OOP Diskussion die Punkte die dir nicht gefallen.

    Jow, ich ignoriere euch immer.

    Ich mache Dinge, die funktionieren, Du sagst, was ich mache ist Scheiße und ich ignoriere das.
    Stimmt.
    Wenn Du mir Argumente bietest, die mir unbekannt sind und ich dann feststelle, dass ich eine Einschätzung überdenken und ändern muss, dann ignoriere ich diese auf keinen Fall - selbst, wenn sie in einer Beleidigung verpackt wären.

    Die OOP-Diskussion brachte auch mir Neues, was neu war wurde nicht ignoriert, sondern durchaus nachrecherchiert. Es war nichts dabei, was im Widerspruch zu meinen Äußerungen steht oder mir zeigt, dass meine Herangehen ungenau wäre.

    Shade Of Mine schrieb:

    Auch wenn du es wieder ignorieren wirst:
    nenn mir mal die Vorteile von deiner Methode gegenüber nicht vererben.

    Habe ich oben, es vereinfacht den Umgang mit der entsprechenden zu flaggenden Klasse und es erhöht die Produktivität.

    Shade Of Mine schrieb:

    Schreibarbeit ist der einzige Vorteil. Es kann keinen anderen geben als Syntax weil es technisch gleichwertig mit "w->Mode" ist.

    Es ist technisch gleichwertig zu w->Mode. Aber C ist auch technisch auch nicht mächtiger als C++, dennoch sehe ich in C++ einige Vorteile.
    C++ ist eigentlich ein Meilenstein für Schreibfaule.

    Shade Of Mine schrieb:

    Es gibt eine Menge pitfalls die man beachten muss damit dein Code korrekt läuft. zB w&d ist etwas dass man sehr sehr leicht übersehen kann.

    Natürlich kann man sich w&d auch aufhängen. Flags von Objekten gegeneinander zu setzen, hat einfach keinen nennenswerten Sinn. Wer einem Programm merkwürdige Fragen stellt, muss mit merkwürdigen Antworten rechnen. Und selbst das passiert hier nicht.
    w&d sind entweder Flags oder mehrdeutig und müssen daher für dem Compiler und damit im Code für den Leser erkennbar erklärt werden.

    Shade Of Mine schrieb:

    Dazu eben die von mir genannten logischen Probleme die ich genannt habe.

    Ich ignoriere Deinen Text nicht, aber sehe Deine Probleme damit nicht, bzw. bewerte sie anders.

    Shade Of Mine schrieb:

    PS:

    if(win) {
    }
    

    was genau macht das eigentlich?
    testet es ob das fenster in einem guten zustand ist? oder ist es der test auf flags?
    lässt sich alles natürlich definieren - aber wo bleibt die intuition?

    Keine Ahnung.

    Was testen if(win) denn, wenn es nicht von etwas anderem abgeleitet ist?
    Ist bool operator() grundsätzlich beschrieben und wenn ja wie?
    Und ist das intuitiver?



  • DEvent schrieb:

    Also was geht alles:

    window = Flags::Fullscreen; // weist dem Window den Flag Fullscreen zu
    window = Flags::Modal; // weist dem Window den Flag Modal zu
    window = Flags::Fullscreen | Flags::Modal; // weist dem Window beide Flags zu?
    if ( window & Flags::Fullscreen ) // testet, ob Window den Flag Fullscreen hat
    window = window2; // ??
    if ( window & window2 ) // ??
    if ( window ) // ??
    

    wieso die fragezeichen?

    window = window2; // window kriegt alle flags von window2
    if ( window & window2 ) // ergibt 'true' wenn mindens 2 flags identisch sind
    if ( window ) // sind irgendwelche flags gesetzt?
    

    so sehe ich das (intuitiv), wenn flags setzen mit = gemacht wird wie oben.
    will man missverständnisse vermeiden, dann besser so: window.flags = Flags::blahblah;



  • Xin schrieb:

    ulfbulf schrieb:

    eine Window klasse von einer WIndowFlags klasse abzuleiten macht keinen sinn 👎
    ach ne moment sind ja eh alles kiddies hier also schnauze cstoll shade etc. 🤡 😋

    Solange Du nicht Mann genug bist, mit einer erkennbaren Identität gegen mich zu trollen, so troll dich. Kritik gegenüber bin ich offen, derartige Pöpeleien machen aus dem Forum einen Kindergarten. Also werd erwachsen.

    versteh ich nicht, ich hab lediglich gesagt dass ich deine meinung nicht teile. sobald jemand deine meinung nicht teilt ist das getrolle? 😕
    angegriffen hab ich auch nur cstoll und shade, also warum beziehst du das posting auf dich? die welt dreht sich nämlich nicht immer nur um dich...
    als trollerei empfind ich eher die quote wars die du hier versuchst mit shade wieder abzuziehen 🙄

    Solltest Du derjenige IRC-Admin sein, der mich im #cpp mit der Begründung gebannt hat, weil er mich im Forum nicht mag und mich nicht aus dem Forum werfen kann, dann kann ich Dir nur sagen: Die Pubertät sollte mit 20 langsam abgeschlossen sein.

    haha, nein tut mir leid, ich bin weder angemeldet in diesem forum, noch jemals in #cpp gewesen, aber trotzdem gut gemacht 🤡 👍



  • DEvent schrieb:

    Also was geht alles:

    window = Flags::Fullscreen; // weist dem Window den Flag Fullscreen zu
    window = Flags::Modal; // weist dem Window den Flag Modal zu
    window = Flags::Fullscreen | Flags::Modal; // weist dem Window beide Flags zu?
    

    Das passt, weil Modal und Fullscreen beide Flags sind - ist aber nicht das, was weiter oben kritisiert wird.
    Da ist Modal ein DialogFlag und Fullscreen ein WindowFlag. Unterschiedliche Klassen => bei Shade geht es nicht.

    Undertaker schrieb:

    window = window2; // window kriegt alle flags von window2
    

    Yepp, sofern nicht überschrieben bzw. ambivalent.

    Undertaker schrieb:

    if ( window & window2 ) // ergibt 'true' wenn mindens 2 flags identisch sind
    

    Yepp, sofern nicht überschrieben bzw. ambivalent.

    Undertaker schrieb:

    if ( window ) // sind irgendwelche flags gesetzt?
    

    Nur wenn bool operator() beschrieben ist. Ist bei mir nicht, weil die Frage ist in der Regel Unsinn. Schließlich stellt man bis zu 32 Fragen gleichzeitig und nicht alle Antworten müssen eine Bedeutung für die Fragestellung haben. Das wäre ein klassischer Bug, nachdem man Flags (egal ob als enum, class oder einfache #defines) erweitert.
    Für aufwendige Abfragen kann die Flagklasse um entsprechende Funktionen oder Flagpackete erweitert werden.

    if( window & WindowFlags::GameCapabilities )
    oder 
    if( window.HasGameCapabilities() )
    statt
    if( window & WindowFlags::OpenGL && window & WindowFlags::FullScreen && window & WindowFlags::NoBorders )
    

    Undertaker schrieb:

    will man missverständnisse vermeiden, dann besser so: window.flags = Flags::blahblah;

    Wenn ihr eine Erweiterung der Konvention als ein derartiges Risiko einschätzt, solltet ihr davon natürlich absehen.
    Für mich stellt sich die Frage nach der Verwendung, bei Flags kommt selten operator = zur Verwendung, vorrangig operator & und operator |=, bzw. &= und ~.
    Flags beantwortet schließlich nicht eine Frage, sondern mehrere und mit operator = modifiziert man grundsätzlich alles - was in der Regel nicht gewünscht ist.



  • Xin schrieb:

    CStoll schrieb:

    Xin schrieb:

    CStoll schrieb:

    Es gibt kein Chaos, da Window sich genauso verhält, als wäre es mit Window::Flags implementiert worden.

    Du hast mir immer noch nicht verraten, was der Ausdruck 'wnd1&wnd2' für eine Bedeutung haben soll.

    Wenn operator & für zwei Fenster nicht deklariert ist, würde eine Hirachie hochgegangen und das Ergebnis wären übereinstimmende WindowFlags, genauso wie wnd1->Flags & wnd2->Flags.
    Wenn Dir das nicht gefällt, deklariere operator & als private member.

    Ist dir klar, daß du dadurch auch die (normal erlaubten) Aufrufe wie 'w&Window::FullScreen' wieder außer Gefecht setzt?

    Nopes, ist mir nicht klar.
    operator & ( Window &, Window & ) fängt w&d ab, aber nicht w & WindowFlag::FullScreen.

    Kennst du den Unterschied zwischen Überladung und Überdeckung? Wenn du in der Window-Klasse einen operator& (privat) definierst, verdeckt der den op&(WindowFlags&) aus der Flag-Klasse - ergo müsstest du diesen per using nachziehen, um ihn noch nutzen zu können. (bei der Alterantive mit einem globalen op&(WindowFlags&,WindowFlags&) bin ich mir nicht sicher, wer für die Überladung einbezogen wird.

    CStoll schrieb:

    Und dafür benötigt die Window-Klasse dann ein halbes Dutzend Zuweisungsoperatoren (und je tiefer du in die Hierarchie runtersteigst, desto mehr werden es ;)).

    Und? Sind alle eindeutig, werden vererbt und es gibt keine tausenden von Funktionen.

    Sie werden eben nicht vererbt, sondern vom (notfalls automatisch generierten) Zuweisungsoperator überdeckt.

    Man muss schon wissen, was man tut und dass die Flags nicht in einer Vererbungslinie stehen dürfen, weil sie sonst doppelt auftreten, ist wohl klar. Darum Templates, damit man eben nicht eine Vererbungslinie aufbaut.

    Ja, man muß wissen, was man tut - und auch auf die Gefahr hin, mich zu wiederholen: Du wirst nicht der einzige bleiben, der durch dieses Gewirr durchblicken muß.

    Xin schrieb:

    DEvent schrieb:

    Also was geht alles:

    window = Flags::Fullscreen; // weist dem Window den Flag Fullscreen zu
    window = Flags::Modal; // weist dem Window den Flag Modal zu
    window = Flags::Fullscreen | Flags::Modal; // weist dem Window beide Flags zu?
    

    Das passt, weil Modal und Fullscreen beide Flags sind - ist aber nicht das, was weiter oben kritisiert wird.
    Da ist Modal ein DialogFlag und Fullscreen ein WindowFlag. Unterschiedliche Klassen => bei Shade geht es nicht.

    Das Problem ist dabei auch die unterschiedliche Bedeutung der Anweisungsfolgen, je nach beteiligten Werten:

    window=WF::Fullscreen;
    window=WF::SysMenu;
    

    ->Window hat nur SysMenu-Stil

    window=WF::Fulscreen;
    window=DF::Modal;
    

    ->Window hat beide Stile.

    Undertaker schrieb:

    window = window2; // window kriegt alle flags von window2
    

    Yepp, sofern nicht überschrieben bzw. ambivalent.

    Undertaker schrieb:

    if ( window & window2 ) // ergibt 'true' wenn mindens 2 flags identisch sind
    

    Yepp, sofern nicht überschrieben bzw. ambivalent.

    Siehst du - und dafür, daß sie nicht überschrieben werden, mußt du selber sorgen.

    Für mich stellt sich die Frage nach der Verwendung, bei Flags kommt selten operator = zur Verwendung, vorrangig operator & und operator |=, bzw. &= und ~.
    Flags beantwortet schließlich nicht eine Frage, sondern mehrere und mit operator = modifiziert man grundsätzlich alles - was in der Regel nicht gewünscht ist.

    Und nun rudert er selber wieder zurück - auch interessant zu sehen 😃 (Fakt ist - du hast den op= und damit wird er auch verwendet).

    PS: Ich hätte zwei Möglichkeiten anzubieten:

    1. Verwendung von Membern - bei "wnd.flag = ..." ist klar, was es darstellen soll
    2. Vererbung, aber dann ohne Operatoren, sondern mit Methoden wie : "wnd.SetFlag(Fullscreen)", "wnd.ResetFlag(FullScreen)", "wnd.HasFlag(FullScreen)"

    Beides vermeidet die Unstimmigkeiten, die dein Design heraufbeschwört.



  • window = window2;
    

    Gefällt mir am besten 🙂
    Der Leser des Codes hat keine Ahnung was das macht. Ist das nicht herrlich?

    Und dass wir immer noch keine Lösung für

    if(win)
    

    ist auch toll.

    Prüft es ob generell Flags gesetzt sind? Oder prüft es ob das Window in einem "guten" Zustand ist bzw. offen ist?

    Natürlich kann man diese Situationen fest definieren und den Anwender des Codes zwingen es sich zu merken. Das lustige ist aber, wenn man die herkömmliche Methode verwendet:

    window.mode = window.mode;
    

    bzw.

    if(window.mode)
    

    ist es sofort klar was gemeint ist. Es gibt keinen Spielraum für Doppeldeutigkeiten.

    Und wenn ich eins gelernt habe, dann das Doppeldeutigkeiten eine furchtbare Fehlerquelle sind.

    Von den ganzen Fallen die diese tolle Syntax hat mal abgesehen. Man muss höllisch mit den operatoren aufpassen - was für welche Typen definiert ist, dabei muss auch die Sichtbarkeit beachtet werden.

    Statt dem lustigen

    Window window;
    window = WndMode::Fullscreen;
    window = WndFlags::Modal;
    

    könnte ein lustiger Anwender auf die Idee kommen

    Window window;
    window = Window::Fullscreen;
    window = Window::Modal;
    

    zu schreiben.

    Die möglichen Komplikationen bei Vererbung mal aussen vorgelassen.

    Pitfalls über Pitfalls.

    Und das alles nur für weniger Schreibarbeit. Ob es das Wert ist, darf sich jeder selber ausdenken.



  • CStoll schrieb:

    Ja, man muß wissen, was man tut - und auch auf die Gefahr hin, mich zu wiederholen: Du wirst nicht der einzige bleiben, der durch dieses Gewirr durchblicken muß.

    Darum entwirre ich es 🙂

    Ich habe übrigens ein Argument gegen die mehrfache Verwendung, das ihr noch nicht habt.

    CStoll schrieb:

    Das Problem ist dabei auch die unterschiedliche Bedeutung der Anweisungsfolgen, je nach beteiligten Werten:

    window=WF::Fullscreen;
    window=WF::SysMenu;
    

    ->Window hat nur SysMenu-Stil

    Erstaunlich. Das ist überzeugend, das wäre bei

    window->Flags = WF::Fullscreen;
    window->Flags = WF::SysMenu;
    

    natürlich ganz anders.

    Unfähigkeit ist kein Argument gegen eine Technik, sondern ein Argument gegen Programmierung. Wer unfähig ist, wird Fehler unabhängig von der Technik prodizieren.

    CStoll schrieb:

    Und nun rudert er selber wieder zurück - auch interessant zu sehen 😃 (Fakt ist - du hast den op= und damit wird er auch verwendet).

    Steine liegen am Wegrand herum. Trotzdem werden sie selten verwendet, um auf andererleuts Köpfen einzuschlagen. Du hast den Stein und damit wird er auch verwendet?

    CStoll schrieb:

    PS: Ich hätte zwei Möglichkeiten anzubieten:
    Verwendung von Membern - bei "wnd.flag = ..." ist klar, was es darstellen soll

    Die Tatsache, dass ich etwas anderes mache, bedeutet ja nicht, dass ich dies hier ablehne. Ich habe eine Alternative vorgeschlagen und das hier nicht verboten.

    CStoll schrieb:

    Vererbung, aber dann ohne Operatoren, sondern mit Methoden wie : "wnd.SetFlag(Fullscreen)", "wnd.ResetFlag(FullScreen)", "wnd.HasFlag(FullScreen)"
    Beides vermeidet die Unstimmigkeiten, die dein Design heraufbeschwört.

    Und die zweite Möglichkeit ist genau das, was ich mache. Nur heißt operator & bei Dir HasFlag usw.
    Ich möchte ja nicht drauf rumreiten, aber vielleicht fällt Dir grade auf, dass Du gegen Dich selbst argumentiert, denn das Umbennenen von Funktionen ändert eine Technik nicht.

    Shade Of Mine schrieb:

    window = window2;
    

    Gefällt mir am besten 🙂

    Dir sollte man auch keine Steine in die Hand geben.

    Nebenher sollten Flags gesetzt und entfernt werden. Der Gleichoperator ist bestenfalls zur Initialisierung und ansonsten bestenfalls eine Fehlerquelle - unabhängig ob als Klasse oder int.

    Shade Of Mine schrieb:

    Und dass wir immer noch keine Lösung für

    if(win)
    

    ist auch toll.

    Prüft es ob generell Flags gesetzt sind? Oder prüft es ob das Window in einem "guten" Zustand ist bzw. offen ist?

    Zum Einen: Die Frage habe ich Dir schonmal beantwortet, Du wiederholst Dich.
    Zum anderen: Die Frage ist nicht intelligenter geworden, denn (nochmals) erstens: es ist in der Regel unsinnig 32 unabhängig Fragen gleichzeitig zu stellen und nur abhängig davon zu reagieren, ob alle Fragen die Antwort "Nein" liefern.
    Zweitens: Das ist das Standardverhalten von Klassen. Meine Klasse liefert ein Standardverhalten. Was Du kritisierst hat also nichts mit der Flag-Klasse zu tun, sondern ist bei jeder Klasse so. Was Du hier - wiederholt - von Dir gibst, hat also auch nichts mit der Thematik zu tun.

    Du kannst ganz toll argumentatieren...

    Shade Of Mine schrieb:

    Natürlich kann man diese Situationen fest definieren und den Anwender des Codes zwingen es sich zu merken.

    Der Punkt ist nicht, dass es zuviele Antworten gibt - es gibt keine, also musst Du Deine Frage vernünftig formulieren.

    Shade Of Mine schrieb:

    Das lustige ist aber, wenn man die herkömmliche Methode verwendet:

    if(window.mode)
    

    ist es sofort klar was gemeint ist. Es gibt keinen Spielraum für Doppeldeutigkeiten.

    Was ist denn jetzt gemeint? Von 32 unabhängigen Fragen gibt mindestens eine Frage ein "Ja" zurück? Hoffentlich nicht eine, die nichts mit dem Algorithmus zu tun hat und die nachträglich implementiert wurde.
    Was hier klar gemeint ist, ist eine wunderbare Gelegenheit, einen Fehler zu bauen.

    Shade Of Mine schrieb:

    Und wenn ich eins gelernt habe, dann das Doppeldeutigkeiten eine furchtbare Fehlerquelle sind.

    ...und jetzt leg die Steine bitte wieder zurück. Du hast aus if( win ) grade if( win.mode ) gemacht, wo der Compiler Dich nicht auf den Unsinn hinweisen kann. Setze lieber um, was Du gelernt hast.

    Shade Of Mine schrieb:

    Statt dem lustigen

    Window window;
    window = WndMode::Fullscreen;
    window = WndFlags::Modal;
    

    könnte ein lustiger Anwender auf die Idee kommen

    Window window;
    window = Window::Fullscreen;
    window = Window::Modal;
    

    zu schreiben.

    Und? Wenn Du eine Klasse ableitest, guckst Du nicht, wovon Du ableitest, was Du überschreiben solltest und was Du auf keinen Fall überschreiben solltest. Und wenn Du mit Steinen um Dich wirfst, guckst Du auch nicht wohin?
    Dann solltest Du Kieshändler werden. 😉

    So, nun mal ein brauchbares Argument gegen die mehrfache Verwendung von Flag-Klassen. Ich brauchte bisher nicht mehrere davon in einem Objekt. Ich habe eben nochmal damit experimentiert, damit ich mich hier nichts falsches erzähle und folgendes passierte: GCC kompiliert es nicht.

    Die Fehlermeldung lautet: der Operatoraufruf ist mehrdeutig. Er ist aber nicht mehrdeutig, es ist sogar sehr eindeutig. Und der Compiler stimmt mir auch zu, benutzt man globale Operatoren, ist auf einmal alles wieder eindeutig, obwohl der zuvor "mehrdeutige" Code nicht verändert wurde.

    Soweit ich weiß, gibt es zwischen den beiden Möglichkeiten, Operatoren zu definieren, keinen semantischen Unterschied. Entweder liege ich da falsch oder der GCC. Grundsätzlich vertraue ich dem Compiler, aber der GCC hätte mein Vertauen nicht zum ersten Mal enttäuscht.

    Ich werde also noch etwas recherchieren, wer von uns beiden hier recht hat. Egal, wer recht hat, der GCC frisst es zur Zeit nicht, was ein klares Argument dafür ist, bei mehrfacher Verwendung von Flagklassen, diese als Member zu verwenden.



  • Xin schrieb:

    Ich habe übrigens ein Argument gegen die mehrfache Verwendung, das ihr noch nicht habt.

    CStoll schrieb:

    Das Problem ist dabei auch die unterschiedliche Bedeutung der Anweisungsfolgen, je nach beteiligten Werten:

    window=WF::Fullscreen;
    window=WF::SysMenu;
    

    ->Window hat nur SysMenu-Stil

    Erstaunlich. Das ist überzeugend, das wäre bei

    window->Flags = WF::Fullscreen;
    window->Flags = WF::SysMenu;
    

    natürlich ganz anders.

    Unfähigkeit ist kein Argument gegen eine Technik, sondern ein Argument gegen Programmierung. Wer unfähig ist, wird Fehler unabhängig von der Technik prodizieren.

    Aber bei der Variante mit expliziten Flags sieht man, ob man nun das selbe Flag beeinflusst/überschreibt oder nicht:

    vergleich mal:

    dlg = Dialog::Fullscreen;//ist eigentlich WindowFlag::Fullscreen
    dlg = Dialog::Modal;//ist DialogFlag::Modal
    

    vs.

    dlg.wFlag = Fullscreen;
    dlg.dFlag = Modal;
    

    CStoll schrieb:

    Und nun rudert er selber wieder zurück - auch interessant zu sehen 😃 (Fakt ist - du hast den op= und damit wird er auch verwendet).

    Steine liegen am Wegrand herum. Trotzdem werden sie selten verwendet, um auf andererleuts Köpfen einzuschlagen. Du hast den Stein und damit wird er auch verwendet?

    Kennst du Murphy's Gesetz? Wenn du einen Operator anbietest, wird auch irgendjemand auf die glorreiche Idee kommen, ihn zu verwenden. Und selbst wenn du so diszipliniert bist, nach der Initialisierung des Fensters nur noch über op|= und op& die Flags zu verwenden, wirst du das kaum von jedem deiner Kollegen voraussetzen können.

    CStoll schrieb:

    PS: Ich hätte zwei Möglichkeiten anzubieten:
    Verwendung von Membern - bei "wnd.flag = ..." ist klar, was es darstellen soll

    Die Tatsache, dass ich etwas anderes mache, bedeutet ja nicht, dass ich dies hier ablehne. Ich habe eine Alternative vorgeschlagen und das hier nicht verboten.

    CStoll schrieb:

    Vererbung, aber dann ohne Operatoren, sondern mit Methoden wie : "wnd.SetFlag(Fullscreen)", "wnd.ResetFlag(FullScreen)", "wnd.HasFlag(FullScreen)"
    Beides vermeidet die Unstimmigkeiten, die dein Design heraufbeschwört.

    Und die zweite Möglichkeit ist genau das, was ich mache. Nur heißt operator & bei Dir HasFlag usw.
    Ich möchte ja nicht drauf rumreiten, aber vielleicht fällt Dir grade auf, dass Du gegen Dich selbst argumentiert, denn das Umbennenen von Funktionen ändert eine Technik nicht.

    Der Unterschied liegt in der Semantik - op& hat eine vordefinierte Bedeutung, die jeder Anwender "versteht" (und bei der man erst einmal überlegen muß, was sie mit dem Problem zu tun hat), HasFlag() drückt durch seinen Namen klar aus, was es für eine Aufgabe hat.
    (und auch auf die Gefahr, mich zu wiederholen, ein Fenster "ist" kein Flag, sondern bestenfalls ein Flagbares Objekt)

    Shade Of Mine schrieb:

    window = window2;
    

    Gefällt mir am besten 🙂

    Dir sollte man auch keine Steine in die Hand geben.

    Wenn du Angst um deine Gesundheit hast, dann solltest du alle erreichbaren Steine schnell wegschließen. Oder würdest du eine geladene Pistole auf dem Tisch liegen lassen, nur mit einem Zettel "bitte nicht anfassen" geschützt?

    Shade Of Mine schrieb:

    Und dass wir immer noch keine Lösung für

    if(win)
    

    ist auch toll.

    Prüft es ob generell Flags gesetzt sind? Oder prüft es ob das Window in einem "guten" Zustand ist bzw. offen ist?

    Zum Einen: Die Frage habe ich Dir schonmal beantwortet, Du wiederholst Dich.
    Zum anderen: Die Frage ist nicht intelligenter geworden, denn (nochmals) erstens: es ist in der Regel unsinnig 32 unabhängig Fragen gleichzeitig zu stellen und nur abhängig davon zu reagieren, ob alle Fragen die Antwort "Nein" liefern.

    Es ist möglich - und irgendwer wird so clever sein, es auch zu machen (und wenn die Window-Klasse nicht explizit dagegensteuert, wird kein Compiler der Welt so einen Müll verhindern)

    Shade Of Mine schrieb:

    Natürlich kann man diese Situationen fest definieren und den Anwender des Codes zwingen es sich zu merken.

    Der Punkt ist nicht, dass es zuviele Antworten gibt - es gibt keine, also musst Du Deine Frage vernünftig formulieren.

    Nein, der Punkt ist, daß du die Semantik des Programms hinter (für Außenstehende) unplausiblen Operatoren und impliziten Typumwandlungen versteckst, statt dem Kind einen Namen zu geben.

    Und? Wenn Du eine Klasse ableitest, guckst Du nicht, wovon Du ableitest, was Du überschreiben solltest und was Du auf keinen Fall überschreiben solltest. Und wenn Du mit Steinen um Dich wirfst, guckst Du auch nicht wohin?
    Dann solltest Du Kieshändler werden. 😉

    Da sind wir wieder bei der Disziplin der Programmierer - du machst es dir einfach, deine Flag-Klasse zu erstellen. Aber jeder, der irgendwas an deinem Framework machen will, muß die Existenz der Klasse bedenken und ein halbes Dutzend Hilfsmethoden implementieren, die nichts machen außer die Anwendbarkeit dieser Flag-Klasse(n) sicherzustellen.

    So, nun mal ein brauchbares Argument gegen die mehrfache Verwendung von Flag-Klassen. Ich brauchte bisher nicht mehrere davon in einem Objekt. Ich habe eben nochmal damit experimentiert, damit ich mich hier nichts falsches erzähle und folgendes passierte: GCC kompiliert es nicht.

    Die Fehlermeldung lautet: der Operatoraufruf ist mehrdeutig. Er ist aber nicht mehrdeutig, es ist sogar sehr eindeutig. Und der Compiler stimmt mir auch zu, benutzt man globale Operatoren, ist auf einmal alles wieder eindeutig, obwohl der zuvor "mehrdeutige" Code nicht verändert wurde.

    Wenn schon der Compiler dir erklärt, daß du Unsinn baust, solltest du es langsam einsehen 😉

    Soweit ich weiß, gibt es zwischen den beiden Möglichkeiten, Operatoren zu definieren, keinen semantischen Unterschied. Entweder liege ich da falsch oder der GCC. Grundsätzlich vertraue ich dem Compiler, aber der GCC hätte mein Vertauen nicht zum ersten Mal enttäuscht.

    Es gibt einen Unterschied zwischen beidem - die Art der Überladungs-Auflösung (das kommen bei Methoden die unterschiedlichen Scopes der beteiligten Klassen dazu, die der Compiler auch mit berücksichtigen muß).

    Ich werde also noch etwas recherchieren, wer von uns beiden hier recht hat. Egal, wer recht hat, der GCC frisst es zur Zeit nicht, was ein klares Argument dafür ist, bei mehrfacher Verwendung von Flagklassen, diese als Member zu verwenden.

    Und schon wird dein Design inkonsequent - alleinstehende Flags als Basisklasse, kombinierte Flags als Member (und wenn du die Klasse später erweitern willst, mußt du sie komplett umbauen, was nicht gerade angenehm für den Verwender ist). Dann habe ich lieber ein konsequentes Design: Alle Flag's sind Member.


Anmelden zum Antworten