Methoden mit bool-Parametern und "Lesbarkeit" im Kontext



  • window = WindowFlags::Fullscreen;     // Flag setzen 
    window = WindowMode::DoubleBuffering; // Mode setzen
    

    Ich finde die Syntax ziemlich elegant.

    if(*win & Fullscreen)
    if(*win & BackBuffering)
    

    Dies ist nich so verwirrend. Normal muss man ja auch machen:

    if ( win->flags & BackBuffering ) // ...
    

    Also ich finde die Syntax ziemlich elegant und auch nicht verwirrend. Es ist nur ungewoehnlich. Probleme bei der Klassenhierarchie sehe ich nicht so. Da alles nur statisch ablaeuft gibts auch keine Nachteile.

    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?

    if ( window & MeineFlags::foo ) { }
    else if if ( window & MeineErweitertenFlags::foo ) { }
    


  • win = Fullscreen | Modal;
    

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

    Btw, endlich mal eine sinnvolle Verwendung von operator overloading 🙂



  • CStoll schrieb:

    [...] wenn da jede Klasse ihre eigenen Flags hat, ist das Chaos vorprogrammiert.

    Im wahrsten Sinne des Wortes. 😃



  • 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?

    CStoll schrieb:

    Windows enthalten WindowFlags und beide können im Bedarfsfall auf die Flags reduziert werden - ob das jetzt per MyWindow->Flags passiert, oder durch eine Typkonvertierung auf WindowFlags macht da keinen Unterschied.

    Du sagst "enthalten" - und das steht ehr für eine "hat-ein"-Beziehung. (btw, ein Fenster enthält auch seine Position, den Text der Titelleiste etc. - soll es dafür auch von Rect, String etc abgeleitet werden?)

    Das ist genau das, was man sich von wiederverwendbaren Klassen wünscht.

    In meinem Klassen gibt's keine Fenster, ich schreibe ja kein OS. Aber was die Titelleiste angeht, finde ich viele Parallelen bei meinen Klassen.
    Icons sind bei mir abgeleitet von u.a. BitMaps (die von Flächen abgeleitet sind) und Strings und Listenelementen und Punkten (Position), weil Icons haben Namen und weil Icons von Strings abgeleitet ist, darf Liste auch nach Namen suchen usw...

    Die Ableitung Bitmap->Icon kann ich ja noch nachvollziehen (wobei der Fall auch schon in Richtung der Rechteck/Quadrat-Problems gehen könnte), aber der Rest klingt für mich nach fehlverstandenem OOP.

    Wo ist das Problem? Ich sehe hier bisher vorrangig Vorteile.

    Was ist daran ein Vorteil, besonders kryptischen Code schreiben zu können?

    CStoll schrieb:

    Ich kann ja nichts dafür, wenn du meine Begründung nicht akzeptiert. Ein Fenster HAT Flags - und ist kein (aufgewertetes) Flag.

    Man kann sich vieles von verschiedenen Perspektiven ansehen. Ich würde mich an Deiner Stelle nicht so allgemeingültig festlegen.

    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).

    CStoll schrieb:

    Potentielle Fehlerquellen? Ist das jetzt einfach nur mal dahergeschrieben oder steckt da eine belegbare Befürchtung hinter?

    Du mußt alle deine Flag-Klassen identisch aufbauen - wenn du da eine Kleinigkeit vergisst, klappt es plötzlich nicht mehr so wie gewünscht. Und zeig mir mal, wie man die Flag-Klassen per Template erzeugen kann.

    Warum müsste ich die Flag-Klassen identisch aufbauen!?

    Was braucht man denn für eine Flag-Klasse? Die typbezogenen Operatoren und die Namen den Wert der Flags.

    Und Werte hinter den Flags, die sinnvolles Arbeiten erlauben (für "einfache" Flags sind nur Zweierpotenzen sinnvoll).

    Keine Ahnung, wo Du potentielle Gefahren siehst, aber wenn Du sie siehst, lass sie mich wissen.

    Siehe oben - schonmal versucht, was bei 'if(w&d)' herauskommt? Sowas ist weder besonders lesbar noch macht es irgendetwas sinnvolles - aber es wird anstandslos compiliert.[/quote]
    Deklariere es als private und es kompiliert nicht mehr. Es ist ja nicht so, als ob diese Sachen nicht möglich wären.
    [/quote]Wenn du den Operator in der Window-Klasse privat deklarierst, schaltest du damit auch den geerbten Operator aus (ich bin mir nicht ganz sicher, inwieweit das mit globalen Operatoren zusammenarbeitet), also mußt du vermutlich mehr machen als "nur" den Operator privat zu deklarieren.

    Hier stelle ich aber auch mal die Frage, ob das w&d wirklich interessant ist. Das hat genausowenig Sinn wie ( w->WindowFlags & d->WindowFlags ). Wozu soll das gut sein? Welche Frage soll das beantworten? Wenn beide Objekte mindestens eine beliebige Gemeinsamkeiten haben, dann...?

    Wenn ich 'w->WindowFlag&d->WindowFlags' schreibe, sehe ich was dahintersteckt - beim 'w&d' müsste ich erstmal überlegen (und eventuell sogar nachsehen).

    Derartige Abfragen kommen in meiner Programmierung äußerst selten vor und dann lässt sich das notfalls auch lesbar darstellen, indem man in diesem eher seltenen Fall dem Leser klarstellt, dass man auf WindowFlags rauswill.

    if( static_cast< WindowFlags & >( window ) & static_cast< WindowFlags & >( dialog ) ) ...
    

    Im alltäglichen Fall - und der ist mir im Alltag wichtiger - ist das nicht erforderlich.

    Du denkst aber auch daran, daß du nicht der einzige bist, der deine Flag-Klassen verwendet 😉 Und selbst wenn ich dir die nötige Disziplin zutraue, deine Kollegen werden bestimmt auf die Idee kommen, es kürzer zu schreiben.

    DEvent schrieb:

    window = WindowFlags::Fullscreen;     // Flag setzen 
    window = WindowMode::DoubleBuffering; // Mode setzen
    

    Ich finde die Syntax ziemlich elegant.

    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 ;)).

    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.



  • 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. 🤡 😋



  • 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 🤡 👍


Anmelden zum Antworten