根据ID值选择正确的派生类

Choose the corect derived based class based on ID value

本文关键字:派生 ID 选择 根据      更新时间:2023-10-16

我在c++中有一个名为InformationElement的类,它定义了以下信息元素框架结构:

-元素ID-> <-元素长度-> <-可变载荷->

  1. 元素ID为1字节
  2. 元素长度为1字节长。它定义有效载荷部分的长度。
  3. 类包含用于内容序列化和反序列化的虚函数+定义ElementID的类型。

从这个类继承不同的派生类,例如:

    <
  1. 类功能/gh>
  2. 类操作。
  3. 类TimingParameters

每个派生类都有一个惟一的Element ID和不同的负载。

不同的信息元素(IEs)将被封装在一个更大的框架中。这个更大的框架包含了封装在其中的信息元素的数量。

& lt;数量IEs -> & lt;,即1 -> & lt;——即2 -> & lt; 3 --> ......

从发送方的角度来看,序列化这些信息没有问题。然而,在接收方端,接收方必须提取Element ID,并根据该值选择正确的派生类来处理有效负载部分,即处理反序列化操作。在接收端进行此操作的传统方法是构建一个大的开关箱,如下所示:

InformationElement *element;
switch (elementID)
{
  case 1:
    element = new Capabilties;
  case 2:
    element = new Operation;
  case 3:
    element = new TimingParameters;
}

然而,如果我有100个元素,它就太多了,无法进行比较,并且它不会扩展那么多。

所以我的问题是有任何聪明的方法做到这一点在c++比插入一个唯一的情况下,每个独立的元素ID?

我建议使用工厂。看助推。功能/工厂的合理实现。

如果你不想使用boost, Factory,来自wikibooks,展示了一个简化的c++实现,可以帮助你开始。

维基教科书讨论的一个大遗漏是缺乏半自动注册,这在这篇博客文章《c++中的工厂设计模式》和两篇关于CodeProject A c++对象工厂和c++中的工厂模式的文章中都有讨论。

当然,这也有一个SO的答案:是否有一种方法来实例化对象从一个字符串持有他们的类名?

switch - case,用等价的东西代替。例如,

typedef InformationElement * (*ElementCreatorFunction)();
std::map< ElementEnum, ElementCreatorFunction > ElementCreatorMap {
    { 1, []() -> InformationElement * { return new Capabilities; } },
    { 2, []() -> InformationElement * { return new Operation; } },
    { 3, []() -> InformationElement * { return new TimingParameters; } }
};
InformationElement * element = ElementCreatorMap[ elementID ] ();

允许运行时定制和模块化。"case "的主体可以在不同的源文件中,也可以在动态加载的模块中。

一个较小的改变是用类似但更安全的语句替换容易出错的switch - case语句。我的safe_switch库提供了CASE,而不需要break;,在你的例子中已经忘记了。

顺便说一下,看起来std::unique_ptr< InformationElement >可能比InformationElement *更合适。