2014-01-22 98 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 ""; 
    } 
};