design frage enums flags und co



  • hallo leute

    als beispiel will ich einen wrapper um FindFirstFileEx und FindNextFile bauen.

    FindFirstFileEx hat unter anderem folgende parameter:

    typedef enum _FINDEX_INFO_LEVELS { 
      FindExInfoStandard,
      FindExInfoBasic,
      FindExInfoMaxInfoLevel
    } FINDEX_INFO_LEVELS;
    
    typedef enum _FINDEX_SEARCH_OPS { 
      FindExSearchNameMatch,
      FindExSearchLimitToDirectories,
      FindExSearchLimitToDevices
    } FINDEX_SEARCH_OPS;
    
    DWORD AdditionalFlags; /* #define FIND_FIRST_EX_CASE_SENSITIVE und FIND_FIRST_EX_LARGE_FETCH
    

    ich will nun fuer die drei parameter eigene enums anlegen.
    aber wo macht man das am besten ?

    der wrapper heisst schlicht find_first und liegt im namespace 'win'.

    legt man die enums frei in den win-namespace ? oder in die find_file klasse ?
    oder doch besser drei weitere klassen bauen wo die entsprechenden enums drinnen sind ?

    /* beispiel */
    class info_levels
    {
       public:
          enum
          {
             info_standard,
             info_basic,
             max_info_level
          };
    
          DWORD flags;
    };
    

    dann ist wiederrum der klasssennamen eher schlecht als recht. da fehlt dann der bezug zu find_file. also dann als nested class von find_file ? oder wieder ein neuer namespace ?
    artet dann bei der benutzung in viel schreibarbeit aus.

    wie macht ihr sowas ?

    Meep Meep



  • entweder in die find_file klasse oder aber in einen eigenen find_file-artigen namespace (zB find_file_types, find_file_levels, etc.)

    Sofern diese enums nur für die find_file Klasse da sind, würde ich sie in die Klasse packen, wenn sie auch woanders verwendet werden können, dann ein eigener namespace.

    PS:
    das ist mein Ansatz für das Problem - prinzipiell ist aber alles eine tragbare Lösung, sofern du konsistent bleibst.



  • In C++11 gibts enum class, da muss u.a. der Zugriff zwingend via enumname::value erfolgen, man spart sich also den Namespace.
    Ich würd enum class nehmen und das außerhalb der Klasse machen. Oder, wenn enumname auch unter anderen Umständen verwendet wird, in die dazugehörige Klasse.



  • Nathan schrieb:

    In C++11 gibts enum class, da muss u.a. der Zugriff zwingend via enumname::value erfolgen, man spart sich also den Namespace.
    Ich würd enum class nehmen und das außerhalb der Klasse machen.

    das problem ist das ich einem enum class nur einen wert zuweisen kann und nicht mehrere logisch-verknuepfte, was bei flags oft der fall ist.
    z.b. bei den AdditionalFlags:

    enum class add_flags
    {
       case_sensitive = FIND_FIRST_EX_CASE_SENSITIVE,
       large_fetch    = FIND_FIRST_EX_LARGE_FETCH
    };
    
    add_flags flags = add_flags::case_sensitive & add_flags::large_fetch; /* geht nicht */
    

    man koenne nicht mal large_fetch einer int-variablen zuweisen (meines wissens)



  • Meep Meep schrieb:

    add_flags flags = add_flags::case_sensitive & add_flags::large_fetch; /* geht nicht */
    

    Du willst |, nicht &. Und wer das will muss halt operator| überladen.

    Meep Meep schrieb:

    man koenne nicht mal large_fetch einer int-variablen zuweisen (meines wissens)

    Das ist praktisch immer ein Fehler. Wer's doch will: static_cast.



  • bestfehlerbeschreibungevr schrieb:

    Meep Meep schrieb:

    add_flags flags = add_flags::case_sensitive & add_flags::large_fetch; /* geht nicht */
    

    Du willst |, nicht &.

    da haette ich drauf wetten koennen das da sofort einer drauf anspringt: ich schrieb nur was von ein logischen verknuepfung, also passt & genauso

    bestfehlerbeschreibungevr schrieb:

    Meep Meep schrieb:

    man koenne nicht mal large_fetch einer int-variablen zuweisen (meines wissens)

    Das ist praktisch immer ein Fehler.

    warum ?


Log in to reply