C++ 中的多态枚举
我有这些枚举声明:
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
};
显然我正在重复枚举中的元素。有什么办法可以防止这种情况发生吗?
编辑: 我在通用类上使用“MessageType”通过网络发送它,另一方面我解析此类的对象并调度消息。但我有不同的客户;有些期望仅具有“Request”类型成员的对象,有些期望仅具有“Response”类型成员的对象。
使用“Message”类,我正在创建“DispatcherRequest”。
class Message
{
public:
……….
MessageType messageType;
}
struct DispatcherRequest
{
..........
Request type;
};
I have these Enum declarations:
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
};
Obviously I'm repeating elements in Enum's. Is there any way to prevent this?
EDIT:
I'm using "MessageType" on a general purpose class to send it through network, on the other side I parse the object of this class and dispatch message. But I have different clients; some expects only objects with "Request" type member and some expects only objects with "Response" type member.
Using "Message" class, I'm creating "DispatcherRequest"s.
class Message
{
public:
……….
MessageType messageType;
}
struct DispatcherRequest
{
..........
Request type;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
为什么不尝试这样的事情呢?
Why not try something like this?
如果不知道这种设计背后的想法,这很难说,但您可能会考虑采用更面向对象的方法。大致如下:
This is hard to say without knowing the idea behind this design, but you might consider a more object-oriented approach. Something along the lines of:
您提到了多态枚举,为什么不只使用一种枚举并将其命名为您计划命名基本枚举的任何名称,例如“消息类型”?这将使您避免重复元素。
You allude to polymorphic enumerations, why not just use one enumeration and name it whatever you had planned on naming the base enumeration, say "Message Type"? This would keep you from repeating elements.
如果我对 PeterK 的答案的评论像泥一样清晰,下面是生成的代码:
In case my comment on PeterK's answer is as clear as mud, here's the resulting code:
来自java的间谍(抱歉草稿视图):
Spy from java (sorry for draft view):
在您的代码示例中,枚举 Request 和枚举 Response 中的值具有相同的值(0 表示 REQ_LOGIN 和 RES_LOGIN,1 表示 REQ_GET_FIELD 和 RES_GET_FIELD),并且它们的值不符合枚举 MessageType 中的值(0 表示 REQ_LOGIN,1 表示 REQ_GET_FIELD, 2 表示 RES_LOGIN,3 表示 RES_GET_FIELD)。这不是问题吗?
如果你想拥有一致数量的枚举,你可以尝试以下方法:
这个 enum MessageCategories 和 const int Watermark 对所有类都是通用的。
现在您可以重新定义枚举,如下所示:
在这种情况下,您不需要枚举 MessageType,因为所有枚举代码都是一致的。
In your code example, values from enum Request and enum Response have the same values (0 for REQ_LOGIN and RES_LOGIN and 1 for REQ_GET_FIELD and RES_GET_FIELD), and their values do not comply with values in enum MessageType (0 for REQ_LOGIN, 1 for REQ_GET_FIELD, 2 for RES_LOGIN and 3 for RES_GET_FIELD). Isn't this a problem?
If you want to have consistent numbers of enums, you can try the following aproach:
this enum MessageCategories and const int Watermark are common to all classes.
Now you can redefine your enums like following:
In this case, you don't need your enum MessageType, because all your enum codes are consistent.
你为什么不做这样的事情:
void sendMessage(Request);
void sendMessage(Respond);
简单重载?
why won't you just do something like this:
void sendMessage(Request);
void sendMessage(Respond);
Simple overload?
也许不使用枚举?
我总是觉得 C++ 枚举受到限制......它们只是没有为我的口味提供足够的灵活性。
这里你有多态行为,你可以限制客户端:
Tadaaam!
Perhaps by not using enums ?
I always feel constrained with C++ enums... they just don't offer enough flexibility for my tastes.
Here you have polymorphic behavior, and you can restrict the client:
Tadaaam!
也许我针对这个问题给出的方法可能更适合您的设计目标。为了清楚起见,这里是适合您的问题的代码。
到目前为止,我遇到的唯一警告是,可以使用
==
Request 类型和Response
类型的字段> 或!=
,无论两者是不同的类型。如果在 C++11 中实现强类型枚举,情况可能并非如此,但我的编译器不支持该功能,因此我无法测试。
希望这有帮助。干杯!
perhaps the approach I gave in response to this question might better suit your design goals. For clarity, here is the code adapted to your question.
The only caveat I've encountered so far is that the fields of the
Request
type andResponse
type can be directly compared to each other using==
or!=
, regardless of the 2 being distinct types.This might not be the case if implementing strongly typed enums in C++11, but my compiler doesn't support that feature, so I can't test.
Hope this helps. Cheers!