2014-01-22 183 views
61

我有一個枚舉類有兩個值,我想創建一個方法,接收值 並返回另一個。我也想保持類型安全(這就是爲什麼我使用枚舉類而不是枚舉)。C++枚舉類可以有方法嗎?

http://www.cplusplus.com/doc/tutorial/other_data_types/沒有提及任何有關方法 但是,我的印象是,任何類型的類都可以有方法。

+4

不,不能。見[這裏](http://en.cppreference.com/w/cpp/language/enum)。 – juanchopanza

+0

@octavian **請注意**我的回答,請重新考慮您的使用案例! –

+0

@πάνταῥεῖ你是完全正確的,我讀過枚舉,但認爲工會,殺死了評論。 –

回答

58

No. C++ enum不是一個類!即使enum class(在C++ 11中強類型枚舉)也不是類,儘管名稱可能會引起誤解。我的猜測是,關鍵詞的選擇是由我們之前C++ 11中使用的模式啓發,得到範圍的枚舉:

class Foo { 
public: 
    enum {BAR, BAZ}; 
}; 

然而,這只是語法。再次,enum class不是class

+46

關於## C++我被告知_「C++的目標是儘可能讓人困惑和專家友好」_。顯然這是一個笑話,但你明白了:) –

+1

一個'union'不是John Doe會考慮的_class_。但他們可以有成員職能。對於成員函數,類實際上不是強制的。使用像'value'或'this'這樣的指示符,像'enum Size {巨大,巨型,啓示錄;布爾運算符<(X rhs)const {return * this

3

other answer中所述,沒有。即使enum class不是一個類。


通常需要有從原因的enum結果的方法,它是不是一個定期(只遞增)枚舉,但那種價值觀的按位定義的被屏蔽或需要其他比特算術運算:

enum class Flags : unsigned char { 
    Flag1 = 0x01 , // Bit #0 
    Flag2 = 0x02 , // Bit #1 
    Flag3 = 0x04 , // Bit #3 
    // aso ... 
} 

// Sets both lower bits 
unsigned char flags = (unsigned char)(Flags::Flag1 | Flags::Flag2); 

// Set Flag3 
flags |= Flags::Flag3; 

// Reset Flag2 
flags &= ~Flags::Flag2; 

顯然,人們認爲封裝必要的操作來重新設置單個/一組比特,例如位掩碼值或者甚至位索引驅動的操作對於處理這樣一組「標誌」將是有用的。

struct/classspecification只是支持更好地訪問枚舉值範圍。沒有更多,不少!

種擺脫限制你不能申報枚舉(類)的方法,無論是使用std::bitset(包裝類),或bitfield union

union s,和這樣的位域聯合體可以有有方法(見here的限制!)。

我有一個樣本,如何轉換位掩碼值(如上圖所示),其相應的位的索引,可以沿着std::bitset這裏使用:BitIndexConverter.hpp
我發現這非常有用的增強可讀性一些'旗'decison爲基礎的算法。

+28

有更多的用例可以保證enum類的方法,例如toString()和fromString()。每種(即使不是這樣)現代主流語言都有(如C#,Java,Swift),而不是C++。 –

+0

讓我們希望下一次統一調用語法... http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4165.pdf – sdgfsdh

5

專注於問題的說明,而不是標題的可能的答案是

struct LowLevelMouseEvent { 
    enum Enum { 
     mouse_event_uninitialized = -2000000000, // generate crash if try to use it uninitialized. 
     mouse_event_unknown = 0, 
     mouse_event_unimplemented, 
     mouse_event_unnecessary, 
     mouse_event_move, 
     mouse_event_left_down, 
     mouse_event_left_up, 
     mouse_event_right_down, 
     mouse_event_right_up, 
     mouse_event_middle_down, 
     mouse_event_middle_up, 
     mouse_event_wheel 
    }; 
    static const char* ToStr (const type::LowLevelMouseEvent::Enum& event) 
    { 
     switch (event) { 
      case mouse_event_unknown:   return "unknown"; 
      case mouse_event_unimplemented: return "unimplemented"; 
      case mouse_event_unnecessary:  return "unnecessary"; 
      case mouse_event_move:   return "move"; 
      case mouse_event_left_down:  return "left down"; 
      case mouse_event_left_up:   return "left up"; 
      case mouse_event_right_down:  return "right down"; 
      case mouse_event_right_up:  return "right up"; 
      case mouse_event_middle_down:  return "middle down"; 
      case mouse_event_middle_up:  return "middle up"; 
      case mouse_event_wheel:   return "wheel"; 
      default: 
       Assert (false); 
       break; 
     } 
     return ""; 
    } 
};