c++ enum类能有方法吗?

时间:2022-05-06 20:44:12

I have an enum class with two values, and I want to create a method which receives a value and returns the other one. I also want to maintain type safety(that's why I use enum class instead of enums).

我有一个包含两个值的enum类,我想创建一个接收一个值并返回另一个值的方法。我还想保持类型安全(这就是为什么我使用enum类而不是枚举类)。

http://www.cplusplus.com/doc/tutorial/other_data_types/ doesn't mention anything about methods However, I was under the impression that any type of class can have methods.

http://www.cplusplus.com/doc/tutorial/other_data_types/没有提及任何关于方法的内容,但是我觉得任何类型的类都可以有方法。

3 个解决方案

#1


63  

No. C++ enum is not a class! Even enum class (strongly typed enums in C++11) are not classes, although the name might be misleading. My educated guess is that the choice of the keywords was inspired by the pattern we used before C++11 to get scoped enums:

不。c++ enum不是类!即使enum类(c++ 11中的强类型枚举)也不是类,尽管名称可能具有误导性。我有经验的猜测是,关键字的选择受到了我们在c++ 11之前使用的模式的启发:

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

However, that's just syntax. Again, enum class is not a class.

然而,这就是语法。同样,enum类不是类。

#2


5  

Concentrating on the description of the question instead of the title a possible answer is

专注于问题的描述而不是题目,一个可能的答案是

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 "";
    }
};

#3


3  

As mentioned in the other answer, no. Even enum class isn't a class.

正如在另一个答案中提到的,没有。即使enum类也不是类。


Usually the need to have methods for an enum results from the reason that it's not a regular (just incrementing) enum, but kind of bitwise definition of values to be masked or need other bit-arithmetic operations:

通常,需要为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;

Obviously one thinks of encapsulating the necessary operations to re-/set single/group of bits, by e.g. bit mask value or even bit index driven operations would be useful for manipulation of such a set of 'flags'.

显然,我们考虑将必要的操作封装到重新/设置单个/组的位上,例如,位掩码值,甚至是位索引驱动的操作,对于操纵这样一组“标志”非常有用。

The struct/class specification just supports better scoping of enum values for access. No more, no less!

c++11 struct/class规范只支持更好地设置枚举值以供访问。不能多也不能少!

Ways to get out of the restriction you cannot declare methods for enum (classes) are , either to use a std::bitset (wrapper class), or a bitfield union.

可以通过使用std:::bitset(包装器类)或位字段联合来摆脱enum(类)的限制。

unions, and such bitfield unions can have methods (see here for the restrictions!).

联合,以及这样的位域联合可以有方法(参见这里的限制!)

I have a sample, how to convert bit mask values (as shown above) to their corresponding bit indices, that can be used along a std::bitset here: BitIndexConverter.hpp
I've found this pretty useful for enhancing readability of some 'flag' decison based algorithms.

我有一个示例,如何将位掩码值(如上所示)转换为它们对应的位索引,可以沿着这里的std::bitset: BitIndexConverter使用这个示例。hpp我发现这对于增强一些基于“标志”的算法的可读性非常有用。

#1


63  

No. C++ enum is not a class! Even enum class (strongly typed enums in C++11) are not classes, although the name might be misleading. My educated guess is that the choice of the keywords was inspired by the pattern we used before C++11 to get scoped enums:

不。c++ enum不是类!即使enum类(c++ 11中的强类型枚举)也不是类,尽管名称可能具有误导性。我有经验的猜测是,关键字的选择受到了我们在c++ 11之前使用的模式的启发:

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

However, that's just syntax. Again, enum class is not a class.

然而,这就是语法。同样,enum类不是类。

#2


5  

Concentrating on the description of the question instead of the title a possible answer is

专注于问题的描述而不是题目,一个可能的答案是

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 "";
    }
};

#3


3  

As mentioned in the other answer, no. Even enum class isn't a class.

正如在另一个答案中提到的,没有。即使enum类也不是类。


Usually the need to have methods for an enum results from the reason that it's not a regular (just incrementing) enum, but kind of bitwise definition of values to be masked or need other bit-arithmetic operations:

通常,需要为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;

Obviously one thinks of encapsulating the necessary operations to re-/set single/group of bits, by e.g. bit mask value or even bit index driven operations would be useful for manipulation of such a set of 'flags'.

显然,我们考虑将必要的操作封装到重新/设置单个/组的位上,例如,位掩码值,甚至是位索引驱动的操作,对于操纵这样一组“标志”非常有用。

The struct/class specification just supports better scoping of enum values for access. No more, no less!

c++11 struct/class规范只支持更好地设置枚举值以供访问。不能多也不能少!

Ways to get out of the restriction you cannot declare methods for enum (classes) are , either to use a std::bitset (wrapper class), or a bitfield union.

可以通过使用std:::bitset(包装器类)或位字段联合来摆脱enum(类)的限制。

unions, and such bitfield unions can have methods (see here for the restrictions!).

联合,以及这样的位域联合可以有方法(参见这里的限制!)

I have a sample, how to convert bit mask values (as shown above) to their corresponding bit indices, that can be used along a std::bitset here: BitIndexConverter.hpp
I've found this pretty useful for enhancing readability of some 'flag' decison based algorithms.

我有一个示例,如何将位掩码值(如上所示)转换为它们对应的位索引,可以沿着这里的std::bitset: BitIndexConverter使用这个示例。hpp我发现这对于增强一些基于“标志”的算法的可读性非常有用。