Flags kombinieren
-
maximAL schrieb:
naja, was heisst missbraucht? immerhin sind die flags dann auch an die klasse gebunden, zu der sie gehören und fliegen nicht sonstwo rum.
aso, ich dachte du willst eine Klasse als namespace missbrauchen. Dabei willst du ja nur sowas wie bei den fstream Klassen.
Dann ists natürlich OK:
Wieso? Wie würdest du es 'Objekt Orientiert' lösen?
ohne flags?
nein, im ernst: das will ich ja grad selbst wissen.Was stört dich an Flags?
nunja, ist das ganze so nicht etwas überflüssig? sagen wir ich hab die klassen Klasse1, Klasse2, Klasse3. und dann steht da:
using namespace Klasse1Flags;
using namespace Klasse2Flags;
using namespace Klasse3Flags;
um die flags zu benutzen. da kann ich mir die namespaces doch auch gleich sparen, oder?Wieso?
Du öffnest den namespace halt lokal...
-
Da hab ich doch gleich mal eine Frage:
enum Foo {bla=1, blub=2};
Sowohl 'bla', als auch 'blub' haben den Typ Foo, korrekt? Wenn ich jetzt 'bla | blub' schreibe werden sie implizit nach int gecastet und verknüpft, korrekt?
Wie mach ich dann folgendes:
void bar (Foo foo); bar (bla | blub); // geht nicht: 'int' kann nicht nach 'Foo' konvertiert werden
Das ist natürlich kacke.
bar (static_cast<Foo>(bla | blub)); // Ne, nicht wirklich, oder?
Was also machen? Eigene Klasse, mit überladenem 'operator |'? Möglich, aber aufwendig. Wie würde man sowas machen?
-
Helium schrieb:
Was also machen? Eigene Klasse, mit überladenem 'operator |'? Möglich, aber aufwendig. Wie würde man sowas machen?
unsigned nehmen
-
unsigned nehmen
Erklär das mal bitte.
Wo unsigend nehmen? Als Argument an die Funktion? das ist doch auch Mist. Dann kann auch jeder schreiben:
bar (42);
Ne, ein wenig Typsicherheit hätte ich schon gerne.
-
unsigned für den Funktionsparameter. Foo würde ja heißen "einen der Werte in der Aufzählung Foo", was hier IMHO noch falscher wäre. Man kann damit zwar niemanden dazu zwingen, die richtigen Konstanten mit dem richtigen Operator zu kombinieren, aber dafür eine eigene Klasse zu schreiben finde ich auch übertrieben - dafür ist das Problem dann doch nicht groß genug
-
Vielleicht sollte ich mal ein offizielles Proposal verfassen, das vorschlägt, dass der Rückgabetyp bitweiser Operatoren bei 'enum'-Instanzen auch ein Objekt vom selben Typ liefern.
-
Helium schrieb:
unsigned nehmen
Erklär das mal bitte.
Wo unsigend nehmen? Als Argument an die Funktion? das ist doch auch Mist. Dann kann auch jeder schreiben:
bar (42);
Ne, ein wenig Typsicherheit hätte ich schon gerne.
dir sollte vollkommen egal sein, was jener oder anderer als Parameter übegibt, du überprüfst ja auf die gesetzte oder nicht gesetzte Bits.
-
OK, ich verwende zwei Bits, dezimal '1' und '2'. Jetzt übergibt jemand einfach '4'. Was jetzt? Ein Fehler, der erst zur Laufzeit aufgefangen werden kann. Bei einer typsicheren Lösung hätte ich gar nicht erst die Möglichkeit etwas falsch zu machen (ich meine unbeabsichtigt).
-
enum color { blue=1, red=2, yellow=4, green=8 }; color c = 7; //sehr intuitiv...
wie willst du das bewerkstelligen? entweder int und prüfen geht so
int a = red | blue; if (a & red) ... if (a & green) ... etc.
oder eben alle werte erlauben und implizit von int zu enumerator konvertieren.
- ersteres finde ich besser, denn wenn ich nicht gerade flags verwende, erwarte ich, dass ein objekt typ color eine farbe von denen ist, die ich vorgebe.
(außerdem: 7.2/5)was du noch tun könntest, wenn du einen kompromis suchst:
Flag operator | (Flag a, Flag b) { return static_cast<Flag>(int(a)|b); }
ein hässlicher workaround..
-
Shade Of Mine schrieb:
Was stört dich an Flags?
dass sie, wenn man sie auf herkömmliche art und weise verwendet (defines bzw. globale consts) keine bindung zur klasse/funktion haben. dann hat man da so eine funktion, die statt selbsterklärender parameter einfach irgendwelche flags will und muss sich erstmal durch den code wühlen, um herauszufinden, was man denn da nehmen könnte.
die sache mit den namespaces ist imho auch nicht so toll. denn da besteht wieder die gefahr, dass ich 2 namespaces gleichzeitig verwende, in denen flags mit gleichem namen sind (sachen wie zb. TRANSPARENT etc. gibts wohl oft mehr als einmal).
"sauber" scheint nur zu sein, wenn ich die flags direkt in die klasse packe, aber dann jedesmal KlasseA::FLAG zu schreiben geht einem auch ganz schnell auf den wecker...