C ++中的多态Enum

时间:2010-06-25 11:03:12

标签: c++ enums polymorphism

我有这些枚举声明:

enum MessageType{  
    REQ_LOGIN,
    REQ_GET_FIELD,       

    RES_LOGIN,
    RES_GET_FIELD
}

enum Request{
    REQ_LOGIN,
    REQ_GET_FIELD
};

enum Respond{
    RES_LOGIN,
    RES_GET_FIELD
};

显然我在重复Enum的元素。有什么方法可以阻止这种情况吗?

编辑: 我在通用类上使用“MessageType”通过网络发送它,另一方面我解析这个类的对象并发送消息。但我有不同的客户;有些人只期望具有“Request”类型成员的对象,而有些人只期望具有“Response”类型成员的对象。

使用“Message”类,我正在创建“DispatcherRequest”。

class Message
{
public:
……….
    MessageType messageType;
}


struct DispatcherRequest
{
..........
    Request type;
};

9 个答案:

答案 0 :(得分:6)

为什么不尝试这样的事情?

enum MainType{  
    REQUEST,
    RESPONSE
};

enum SubType{
    LOGIN,
    GET_FIELD
};

class Message {
   MainType type;
   SubType sub_type;
   ...
};

答案 1 :(得分:4)

如果不了解这种设计背后的想法,这很难说,但您可能会考虑采用更加面向对象的方法。有点像:

class Message {
    public:
        virtual void send() = 0;
};

class Request : public Message {
    public:
        virtual void send();
}

class Response : public Message {
    public:
        virtual void send();
}

答案 2 :(得分:2)

你提到了多态枚举,为什么不只是使用一个枚举,并在命名基本枚举时将其命名为任何名称,比如“消息类型”?这样可以避免重复元素。

答案 3 :(得分:2)

如果我对PeterK的答案的评论和泥浆一样清楚,那么这就是结果代码:

class Message {
public:
    enum MainType {  
        REQUEST,
        RESPONSE
    };
    Message(MainType type_): type(type_) {}
    virtual void send() = 0;
private:
    MainType type;
};

class Request: public Message {
public:
    enum SubType {
        LOGIN,
        GET_FIELD
    };
    Request(SubType sub_type_): Message(Message::REQUEST), 
        sub_type(sub_type_) {}
    virtual void send();
private:
    SubType sub_type;
};

class Response: public Message {
public:
    enum SubType {
        LOGIN,
        GET_FIELD
    };
    Response(SubType sub_type_): Message(Message::RESPONSE), 
        sub_type(sub_type_) {}
    virtual void send();
private:
    SubType sub_type;
};

答案 4 :(得分:0)

来自java的间谍(对不起草稿视图):

class MessageType
{  
protected:
    MessageType(int value);//visible for descending classes only
    MessageType(const MessageType& other);
public:
    static const MessageType REQ_LOGIN, //assign later with integer value
    REQ_GET_FIELD,       

    RES_LOGIN,
   RES_GET_FIELD;
}

clas Request : public MessageType
{
};

clas Respond : public MessageType
{
};

答案 5 :(得分:0)

在您的代码示例中,枚举Request和enum Response中的值具有相同的值(对于REQ_LOGIN和RES_LOGIN为0,对于REQ_GET_FIELD和RES_GET_FIELD为1),并且它们的值不符合枚举MessageType中的值(对于REQ_LOGIN为0,为1对于REQ_GET_FIELD,2表示RES_LOGIN,3表示RES_GET_FIELD)。这不是问题吗?

如果您想拥有一致数量的枚举,可以尝试以下方法:

enum MessageCategories
{
Request = 0,
Response,
AnythingElse
}
const int Watermark = 100;

这个枚举MessageCategories和const int水印对所有类都是通用的。 现在您可以重新定义您的枚举,如下所示:

enum Request
{
REQ_LOGIN = MessageCategories::Request * Watermark,
REQ_GET_FIELD,
REQ_LAST_ITEM,
}
enum Response
{
RES_LOGIN = MessageCategories::Response * Watermark,
RES_GET_FIELD,
RES_LAST_ITEM,
}

在这种情况下,您不需要枚举MessageType,因为所有枚举代码都是一致的。

答案 6 :(得分:0)

为什么你不会这样做:

void sendMessage(Request); void sendMessage(Respond);

简单过载?

答案 7 :(得分:0)

也许不使用枚举?

我总觉得C ++枚举受到限制......他们根本没有为我的品味提供足够的灵活性。

class MessageType
{
public:
  virtual ~MessageType();
  bool operator==(MessageType const& rhs) const;
  bool operator!=(MessageType const& rhs) const;
protected:
  MessageType(const char* type);
private:
  const char* mType;
};

class RequestType: public MessageType
{
public:
  static RequestType const Login() { return RequestType("Login"); }
  static RequestType const GetField { return RequestType("GetField"); }
protected:
  RequestType(const char* type);
};

// same for ResponseType

这里有多态行为,您可以限制客户端:

void someServerFunc(MessageType const& type);

void someClientFunc(RequestType const& type);

Tadaaam!

答案 8 :(得分:0)

或许我回应this question的方法可能更适合您的设计目标。为清楚起见,这里是适合您的问题的代码。

typedef struct{
    enum {
        LOGIN,
        GET_FIELD
    };
}MessageType;

typedef struct : public MessageType {
    //this struct inherits the fields of MessageType,
    //and can be accessed in code like so, Request::LOGIN or Request::GET_FIELD

    //omit this enum declaration if you do not wish to extend the base enum
    enum {
        //additional fields here
    };
}Request;

typedef struct : public MessageType {
    enum {
        //additional fields here
    };
}Response;

到目前为止,我遇到的唯一警告是Request类型和Response类型的字段可以使用==!=直接相互比较,无论2是不同的类型。

如果在 C ++ 11 中实现强类型枚举,可能不是这种情况,但我的编译器不支持该功能,所以我无法测试

希望这会有所帮助。干杯!