enum der richtige Weg?
-
Eine Klassenvariable soll verschiedene zustände haben können: viel, wenig, sehr viel, sehr wenig usw.
Wäre der Ansatz richtig sich dafür eine Aufzählung zu machen so das ich dann sage
Menge m_Menge;
m_Menge = viel;
?
-
ja
-
Hallo,
das ist prinzipiell nicht verkehrt. Es kommt aber darauf an, wie und ob die verschiedenen Zustände das Verhalten der Klasse (bzw. deren Objekte) beeinflussen. Wenn du z.B. viele Methoden hast die etwa so aussehen:void Class::method() { if (m_Menge == seh_viel) { doThis(); } else if (m_Menge == viel) { doThat(); } ... }dann könnte ein polymorphes Objekt (siehe State-Pattern) der bessere Ansatz sein.
-
definitiv
hättest halt dann so was wie:enum Menge={wenig=0x0001,viel=0x0002,sehr_viel=0x0004};kkthxbye
-
ok danke jungs!
-
HumeSikkins schrieb:
Hallo,
das ist prinzipiell nicht verkehrt. Es kommt aber darauf an, wie und ob die verschiedenen Zustände das Verhalten der Klasse (bzw. deren Objekte) beeinflussen. Wenn du z.B. viele Methoden hast die etwa so aussehen:void Class::method() { if (m_Menge == seh_viel) { doThis(); } else if (m_Menge == viel) { doThat(); } ... }dann könnte ein polymorphes Objekt (siehe State-Pattern) der bessere Ansatz sein.
Ich hab mich jetzt mal umgehört, eigentlich benutze ich das ganze dann so wie in deinem Beispiel. Allerdings verstehe ich nicht, wie ich ein state-pattern darauf anwenden könnte? Hast du evtl. ein kleines beispiel dafür?
-
enumerier schrieb:
HumeSikkins schrieb:
Hallo,
das ist prinzipiell nicht verkehrt. Es kommt aber darauf an, wie und ob die verschiedenen Zustände das Verhalten der Klasse (bzw. deren Objekte) beeinflussen. Wenn du z.B. viele Methoden hast die etwa so aussehen:void Class::method() { if (m_Menge == seh_viel) { doThis(); } else if (m_Menge == viel) { doThat(); } ... }dann könnte ein polymorphes Objekt (siehe State-Pattern) der bessere Ansatz sein.
Ich hab mich jetzt mal umgehört, eigentlich benutze ich das ganze dann so wie in deinem Beispiel. Allerdings verstehe ich nicht, wie ich ein state-pattern darauf anwenden könnte? Hast du evtl. ein kleines beispiel dafür?
Da ich deine konkrete Situation nicht kenne, kann ich dir nur ein sehr abstraktes Beispiel geben. Erstmal macht das Ganze wie gesagt nur sinn, wenn a) der Zustand von Menge auf der einen Seite das Verhalten der Klasse ändert und b) der Zustand von Menge variabel ist (also sich dynamisch ändern kann).
Das Ziel ist es, den Code der abhängig vom konkreten Aufzählungswert ausgeführt wird in virtuelle Methoden zu abstrahieren. Aus:
void Class::method() { if (m_Menge == seh_viel) { doThis(); } else if (m_Menge == viel) { doThat(); } ... }wir dann z.B.
void Class::method() { m_Menge.doIt(); }Die Vorgehensweise ist relativ einfach.
Aus der Aufzählung machst du eine abstrakte Klasse. Von dieser leitest du für jeden Wert der Aufzählung eine konkreten Klassen ab. Das Interface der abstrakten Klasse ergibt sich aus der Abstraktion des Codes der abhängig vom konkreten Aufzählungswert ausgeführt wird (im oberen Beispiel ist das doThis und doThat. Das abstrahieren wir z.B. in eine virtuelle Methode doIt).class Menge { public: virtual ~Menge(); virtual void doIt() {} }; class SehrViel : public Menge { public: void doIt() { // Implementation für SehrViel } }; class Viel : public Menge { public: void doIt() { // Implementation für Viel } }; ...In deiner Kontext-Klasse machst du m_Menge dann zu einem Attribut vom Typ Zeiger-auf-Menge. In den Methoden wo du früher den Wert der Aufzählung geändert hast, ersetzt du jetzt das Objekt auf das dein m_Menge-Zeiger zeigt (dazu kannst du jedes mal ein neues Objekt instanziieren (und das alte löschen) oder aber als Optimierung ein Singleton-Objekt für jeden Zustand verwenden).
class Class { public: void f() { m_Menge->doIt(); } private: Menge* m_Menge; // State bzw. Strategy-Objekt };Ob das Ganze jetzt Richtung State oder Strategy wandert ist abhängig davon, wo die Transitionslogik untergebracht ist und wer für den Zustandsübergang zuständig sein soll.