5

私はオープン ソース プロジェクトのコードを調べていて、複数の場合に値をビットシフトすることによって列挙型の値が割り当てられていることに気付きました。これを行う特定の理由はわかりません。また、+1 をインクリメントするだけで値を割り当てるよりも効率が向上することもわかりません。

とにかく、これはおそらく、何が私を混乱させているかを示すコードがなければほとんど意味がありません.

クラス1

enum EventType {
        NONE                = 0,
        PUSH                = 1<<0,
        RELEASE             = 1<<1,
        DOUBLECLICK         = 1<<2,
        DRAG                = 1<<3,
        MOVE                = 1<<4,
        KEYDOWN             = 1<<5,
        KEYUP               = 1<<6,
        FRAME               = 1<<7,
        RESIZE              = 1<<8,
        SCROLL              = 1<<9,
        PEN_PRESSURE        = 1<<10,
        PEN_ORIENTATION     = 1<<11,
        PEN_PROXIMITY_ENTER = 1<<12,
        PEN_PROXIMITY_LEAVE = 1<<13,
        CLOSE_WINDOW        = 1<<14,
        QUIT_APPLICATION    = 1<<15,
        USER                = 1<<16
    };

クラス2

    enum EventType {
        EVENT_MOUSE_DOUBLE_CLICK = osgGA::GUIEventAdapter::DOUBLECLICK,
        EVENT_MOUSE_DRAG         = osgGA::GUIEventAdapter::DRAG,
        EVENT_KEY_DOWN           = osgGA::GUIEventAdapter::KEYDOWN,
        EVENT_SCROLL             = osgGA::GUIEventAdapter::SCROLL,
        EVENT_MOUSE_CLICK        = osgGA::GUIEventAdapter::USER << 1,
        EVENT_MULTI_DRAG         = osgGA::GUIEventAdapter::USER << 2,   // drag with 2 fingers
        EVENT_MULTI_PINCH        = osgGA::GUIEventAdapter::USER << 3,   // pinch with 2 fingers
        EVENT_MULTI_TWIST        = osgGA::GUIEventAdapter::USER << 4    // drag 2 fingers in different directions
    };

これを正しく読んでいる場合、EventType::USER の明示的な値は 65536 またはバイナリで 10000000000000000 です。EVENT_MULTI_TWIST の値は、バイナリで 1048576 または 10000000000000000000 です。

次のようなものを持っているだけでなく、この方法で列挙値を割り当てる目的は何でしょう:

enum EventType {
        NONE                = 0,
        PUSH                = 1,
        RELEASE             = 2,
        DOUBLECLICK         = 3,
        DRAG                = 4,
        MOVE                = 5,
        KEYDOWN             = 6,
        KEYUP               = 7,
        FRAME               = 8,
        RESIZE              = 9,
        SCROLL              = 10,
        PEN_PRESSURE        = 11,
        PEN_ORIENTATION     = 12,
        PEN_PROXIMITY_ENTER = 13,
        PEN_PROXIMITY_LEAVE = 14,
        CLOSE_WINDOW        = 15,
        QUIT_APPLICATION    = 16,
        USER                = 17
    };
4

3 に答える 3

2

これを行う理由は、この方法で定義された列挙型をビットマスクとして使用できるためです。32 ビットの整数を指定すると、列挙値のビットごとの組み合わせを使用してすべてを有効または無効にできる 32 の一意の特性を持つことができます。

たとえば、ビット シフトを使用する実装でリッスンするイベント ハンドラを作成する場合は、単純に を使用できQUIT_APPLICATIONます。各 enum は 1 つのビットであり、それらを組み合わせることで、1 から 16 までの単純な列挙では不可能な方法で、必要なすべてのタイプのイベントを簡単に指定できます。CLOSE_WINDOWQUIT_APPLICATION | CLOSE_WINDOW

提案された「より効率的な」列挙型をリッスンしPUSHて使用するイベント ハンドラーが必要な場合について考えてみてください。RELEASEこれらを OR すると、 になります33あなたの例ではの値でもありDOUBLECLICKます。したがって、どのイベントが本当に必要だったかを知る方法はありません。それは と の組み合わせでしたかPUSHRELEASEそれとも単にでしたDOUBLECLICKか? そのため、列挙型ごとに 1 ビットを予約することが非常に強力です。

次のように定義された列挙値がよく見られます。

enum EventType {
    NONE                =       0,
    PUSH                =     0x1,
    RELEASE             =     0x2,
    DOUBLECLICK         =     0x4,
    DRAG                =     0x8,
    MOVE                =    0x10,
    KEYDOWN             =    0x20,
    KEYUP               =    0x40,
    FRAME               =    0x80,
    RESIZE              =   0x100,
    SCROLL              =   0x200,
    PEN_PRESSURE        =   0x400,
    PEN_ORIENTATION     =   0x800,
    PEN_PROXIMITY_ENTER =  0x1000,
    PEN_PROXIMITY_LEAVE =  0x2000,
    CLOSE_WINDOW        =  0x4000,
    QUIT_APPLICATION    =  0x8000,
    USER                = 0x10000
};

時々、次のようなものも表示されます。

    ...
    CLOSE_WINDOW        =  0x4000,
    QUIT_APPLICATION    =  0x8000,
    CLOSE_AND_QUIT      =  CLOSE_WINDOW | QUIT_APPLICATION,
    ...

ビットシフト表記は読みやすく (一部の人にとっては)、どちらも同じことを行います。列挙された各値は、単一のビットまたはビットの個別の組み合わせを表します (NONEすべてのビットがないことを表す を除く)。

于 2013-09-17T04:12:04.767 に答える