Forward-Declaration für enum einer fremden Klasse?



  • Hi,

    ich habe eine Klasse Line und eine Klasse LineVariant. Line nutzt Komposition für LineVariant und Line hat auch ein enum. LineVariant möchte das enum aber attribuieren. Geht das mit einer Vorwärtsdeklaration in LineVariant.h und wie sähe die dann aus?


  • Mod

    Du möchtest folgendes erreichen?

    // [... Hier ein toller Trick ... ]
    
    class Foo
    {
      Bar::Zahl z;
    };
    
    class Bar
    {
      Foo f;
    public:
      enum Zahl {eins, zwei, drei};
    };
    

    Das ist nicht möglich. Du kannst ähnliche Effekte erreichen, indem du Templates oder Vererbung missbrauchst. Die Frage ist wie immer: Wozu? Das klingt eher so, als wolltest du das enum in einem Namespace haben.



  • Ja, mein Design gefällt mir hier auch nicht.

    Also es ist so: Line ist eine bestimmte Abfolge von Pokeraktionen (z.B. Bet - Call; also eine Bet, gefolgt von einem Call). LineVariant ist eben eine Variante der Line im Bezug auf die Hände, die ein Spieler hier hat, oder auch im Bezug auf die Größe der Einsätze usw.

    Nun zeigt das enum eben an, wie die Abfolge genau ist, also z.B. BET_CALL und BET_FOLD. Basierend darauf geschieht nämlich die Berechnung des Erwartungswerts anders. Jetzt ist es so, dass diese Abfolge von Aktionen ja logisch zur Line gehört, faktisch muss aber LineVariant auch von dieser Abfolge wissen, nämlich um herauszufinden, welche Art von Berechnung erfolgen soll.

    Eine Idee?


  • Mod

    Gibt es einen zwingenden Grund, das Enum in Line zu definieren? Wenn es nicht direkt im Namensraum existieren soll, könnte es ja auch in eine Traits-Klasse verschoben werden. Und wenn dann die Benutzung einfach sein soll, erbst du einfach privat von dieser Traitsklasse.

    // [... Hier ein toller Trick ... ]
    
    struct BarTraits
    {
      enum Zahl {eins, zwei, drei};
    };
    
    class Foo
    {
      BarTraits::Zahl z;
    };
    
    class Bar : private BarTraits
    {
      // Zahl hier benutzbar als ob es als Member deklariert worden wäre
      using BarTraits::Zahl;
      Foo f;
    };
    


  • Ne, zwingenden Grund gibt es nicht. Ich dachte einfach, "es gehört logisch dahin", aber damit komm ich wohl nicht weit.

    Das mit der Traitsklasse verstehe ich nicht, was bringt die? Nur das enum reinstecken und sowohl Line als auch LineVariant davon erben lassen? Wirkt für mich etwas umständlich oder löst man das generell so? 🙂

    Edit: Und was bringt das private Erben im Gegensatz zu einem einfachen BarTraits::... wie Du es auch bei der ersten Klasse gemacht hast? Das ist wegen dem using genau so kurz aber irritiert (mich) weniger.

    Im namespace könnte man das wohl auch halten, ist schon korrekt.


  • Mod

    Eisflamme schrieb:

    Wirkt für mich etwas umständlich oder löst man das generell so? 🙂

    Mir ist nicht bekannt, ob das Problem zu einem bestimmten Archetyp gehört, den man so lösen würde.
    Private Vererbung einfach deshalb, weil es sich um Implementationsdetail handelt, hier geht es ja nicht um Polymorphie oder etwas ähnliches.
    Und durch die Vererbung werden auch gleich noch die Aufzählungskonstanten importiert. In C++11 denkt man da aber ohnehin eher an scoped enumerations (also enum class... wer hat eine gute Übersetzung parat?


Anmelden zum Antworten