Flags? klassen_obj->setFlags(flag::schlafen | flag::duschen | flag::essen);
-
Hallo!
Eine rein theoretische Frage für euch:
Nehmen wir an ich habe eine Klasse und möchte ihr ein bestimmtes Verhalten beibringen, dann ist es etwas aufwändig für jede "eigenschaft" eine Funktion zu vergeben. ( setDuschen(true); ). Mir ist daher dieses | bei der verarbeitung von Dateien (ios::in) und in einigen GUI Toolkits aufgefallen, bei denen man festlegen kann ob zB ein Listeneintrag verschiebbar/löschbar etc. ist. Ich habe noch keien Programmieransatz -> keinen Code
... Wie kann man dieses | verwenden und wie nennt sich dies und was ist es? (zB const int duschen; im namespace flag?)Bitte klärt mich auf!
-
das ist der "or" operator. damit kannst du bits verknuepfen.
0010|0001=0011das klappt dann mit enums auch und du kannst mit einem & (und) operator diese werte abfragen
0011&0010=0010
und so die einzelnen bits/flags herausfinden
ein enum kann z.b. sein
enum autoteil
{
tuer = 1,
frontscheibe =2,
motor =4,
reifen =8,
dach = 16
};und mit
int cabrio = tuer|frontscheibe|motor|reifen;
kombinierst du die flags dann.
-
Das funktioniert ja ganz hervorragend! DANKE!

-
flag::kacken

-
Das hört sich theoretisch ja ganz toll an nur was ist das Gegenteil von flag::reifen? Ich möchte nicht jedesmal alle 200 attribute in setFlags() neu aufführen wenn ich nur eins rausnehmen möchte....
-
dann kannst du den "DWORD" oder "long" oder "int" oder was auch immer holen, in dem die ganzen flags aneinandergereiht sind, und mit dem ^ XOR operator den unnötigen flag entfernen (oder auch wieder hinzufügen):
//ein flag löschen 01001010 ^ 00001000 = 01000010flags= sitzen|essen|lesen; flags=flags^essen; //nur noch sitzen und lesen, die chips sind nähmlich alle :(
-
Oft wird auch eine "changeFlags" Funktion verwendet, die 2 Masken mitbekommt, 1x die Bits welche übernommen werden sollen, und 1x die neuen Zustände für diese Bits:
void foo::changeFlags(unsigned mask, unsigned new_state) { m_flags &= ~mask; m_flags |= (new_state & mask); }
-
Danke für die antworten, ich habe auch mal eine version gebastelt, die mir aber etwas ungeschickt erscheint... kann man das so lassen, oder sie die if-abfragen umständlich, zumal hidden und selectable gar nicht gebaucht werden, da später im code nur überprüft wird ob es sichtbar ist bzw. selektierbar...
enum PointFlags { visible = 1, hidden = 2, movable = 4, not_movable = 8, selectable = 16, not_selectable = 32 };void glPointD::setFlags(int flags) { this->flags = flags; if(flags & hidden) { this->flags = flags ^ visible; this->flags = flags ^ hidden; } if(flags & not_selectable) { this->flags = flags ^ selectable; this->flags = flags ^ not_selectable; } }
-
Warum hasst du visible und hidden gleichzeitig, genau so wie selectable und not_selectable ? Das macht doch logisch keinen Sinn !
1 information an 2 unterschiedlichen stellen = redundanz = poese !Ciao ...
-
Nimm doch std::bitset, da kannst du dann auch die Größe leichter verändern und vor allem mehr als 32 (64) flags haben.
Außerdem gibts hübsche funktionen gratis. DIe bitweisen Verknüpf. operatoren sind in der Klasse überladen.
-
Oh, ein ganz klassische Fall für das State-Pattern

enum PointFlags { visible = 1, hidden = 2, movable = 4, not_movable = 8, selectable = 16, not_selectable = 32 };Wird zu
struct glPointD_visibility { virtual void do_with_visibility() = 0; }; struct glPointD_movability { virtual void do_with_movability() = 0; }: //... struct visible_glPointD : glPointD_visibility { void do_with_visibility() { do_something(); } }; struct hidden_glPointD : glPointD_visibility { void do_with_visibility() { //do nothing } } class glPointD { glPointD_visibility* visiblity; }Es wird immer die jeweilige virtuelle Methode aufgerufen und diese tut entsprechend was anderes (oder auch nichts). Nun können andere Methoden natürlich den Status ändern etc.
Siehe auch:
http://home.earthlink.net/~huston2/dp/state.html
-
Oh, ein klassischer Fall von Overkill.