假设您必须在C ++ 03中设计一个系统,您必须管理来自不同来源的不同类型的消息。
所有消息都有一个共同的属性ID,一个代表消息所含数据的含义的数字。
因此ID与源相关,不同的源可以具有其他源的公共ID。即 SourceA 和 SourceB 可以发送ID设置为1的消息,尽管消息中的数据含义完全不同。
因此,表示消息的基类可以声明如下:
enum SourceType {
SourceA,
SourceB,
// ...
};
struct Message {
virtual int getID();
virtual SourceType getSource();
// ...
};
由于我希望避免在我的代码周围传播幻数,我想将int
替换为更有意义的enum
,但由于每个来源都有他们的不可能拥有不同的枚举。
一种解决方案可能是使用int
返回的信息将enum
转换为正确的getSource
,但这似乎是一种非常完美的设计。
另一个解决方案可能是为所有具有大量重复值(这不是错误)的源定义一个包含所有可能ID的大枚举,如下所示:
enum MessageID {
SourceA_ID1,
SourceA_ID2,
SourceB_ID1,
SourceB_ID2,
// ...
};
因此getID
消息可能会返回MessageID
,但这意味着MessageID将在大小上爆炸,并且可能有点混乱,无法维护和记录。
答案 0 :(得分:1)
选择第一个替代方案:
一个解决方案可能是使用the将int转换为适当的枚举 getSource返回的信息,但似乎非常完美 设计。
基本上enum
等于int
。它作为一种简单的方法来创建常量并避免代码中的幻数。所以有可能:
enum SourceType {
SourceA,
SourceB,
// ...
};
struct Message {
virtual int getID();
virtual SourceType getSource();
// ...
};
// Maybe in "sourceA.h"
enum SourceA_Ids {
SourceA_ID1 = 1,
SourceA_ID2 = 12,
SourceA_ID3 = 20
};
// Maybe in "sourceB.h"
enum SourceB_Ids {
SourceB_ID1 = 1,
SourceB_ID2 = 2,
SourceB_ID3 = 3
};
在你的代码中,直接进行赋值和比较而不需要转换任何内容,因为枚举到int是隐式的:
// sourceA.h
struct MessageFromSourceA: Message {
double data;
...
MessageFromSourceA() {
source = SourceA;
data = 0;
}
};
// sourceA.cpp
void processMsgFromSourceA(Message &msg) {
if (msg.getID() == SourceA_ID1) {
// Send an answer
MessageFromSourceA msga;
msga.id = SourceA_ID2;
msga.data = 123.456;
send(msga);
}
}
如您所见:没有神奇的数字,没有编译错误。