【问题标题】:Returning different enum in overriden method在覆盖方法中返回不同的枚举
【发布时间】:2016-12-11 11:03:48
【问题描述】:

假设您必须在 C++03 中设计一个系统,在该系统中您必须管理来自不同来源的不同类型的消息。

所有消息都有一个共同的属性,即 ID,一个表示消息所包含数据的含义的数字。

所以ID与来源有关,不同来源可以有其他来源的共同ID。即 SourceASourceB 可以发送 ID 为 1 的消息,尽管消息中的数据含义完全不同。

所以表示消息的基类可以声明如下:

enum SourceType {
    SourceA,
    SourceB,
    // ...
};

struct Message {
    virtual int getID();
    virtual SourceType getSource();
    // ...
};

由于我想避免在我的代码周围散布幻数,我想用更有意义的enum 替换int,但由于每个来源都有自己不同的枚举不可能。

一种解决方案可能是使用getSource 返回的信息将int 转换为正确的enum,但这似乎是一个非常完美的设计。

另一种解决方案可能是为具有大量重复值(这不是错误)的所有源定义一个包含所有可能 ID 的大枚举,如下所示:

enum MessageID {
    SourceA_ID1,
    SourceA_ID2,
    SourceB_ID1,
    SourceB_ID2,
    // ...
};

因此getID 消息可能会返回MessageID,但这意味着 MessageID 的大小会爆炸式增长,并且可能有点难以维护和记录。

【问题讨论】:

  • 那么解析调度程序使用SourceType 和消息ID 来实例化正确的有效负载类型?我不确定我是否完全理解你的设计。顺便说一句,谷歌协议缓冲区等系统已经实现了这种使用消息 ID 的延迟解析。
  • 基本上这个想法是有一个系统能够管理来自不同来源的不同消息,每个来源谈论不同的语言,因此解析取决于这对夫妇(来源,消息 ID)。我无法使用第三方库,因为我使用的是具有严格限制的旧嵌入式系统 (PowerPC)。
  • 为什么不返回pair(或tuple,如果可用)?一个组件是源的数字 ID,另一个是消息的数字 ID。这样,接收该对的软件只需知道如何将第一个组件与它们自己的 ID 值匹配,并从那里转换为相应的enum

标签: c++ enums overriding c++03


【解决方案1】:

选择你的第一个选择:

一种解决方案是使用 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);
    }
}

如您所见:没有神奇的数字,没有编译错误。

【讨论】:

    猜你喜欢
    • 2016-09-23
    • 2021-07-18
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2019-01-09
    • 1970-01-01
    相关资源
    最近更新 更多