根据ID值选择基于corect派生的类

时间:2015-08-14 14:23:01

标签: c++ class templates

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

< -Element ID-> < -Element Length->< -Variable Payload->

  1. 元素ID为1 Byte。
  2. 元素长度为1字节长。它定义了有效负载部分的长度。
  3. 该类包含用于内容的序列化和反序列化的虚函数+定义ElementID的类型。
  4. 从这个类中继承了不同的派生类,例如:

    1. class Capabilities
    2. 课程操作。
    3. class TimingParameters。
    4. 每个派生类都有唯一的元素ID和不同的有效负载。

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

      <少数IEs-> < - IE 1 - > < - IE 2 - > < - IE 3 - > ......

      从发射器的角度来看,序列化这些信息没有问题。然而,在接收器侧,接收器必须提取元素ID,并且基于该值,接收器选择正确的派生类来处理有效载荷部分,即处理反序列化操作。在接收器端执行此操作的传统方法是构建如下的大型交换机案例:

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

      但是,如果我有100个元素,那么与它进行比较就太多了,它不会扩展那么多。

      所以我的问题是,在c ++中有什么聪明的方法可以比为每个独立的元素ID插入一个独特的案例更好吗?

2 个答案:

答案 0 :(得分:2)

我建议使用工厂。请参阅Boost.Functional/Factory以获得合理的实施。

如果您不想使用boost,来自wikibooks的Factory显示了一个简化的C ++实现,可能有助于您入门。

wikibooks讨论中的一个重大遗漏是缺少半自动注册,这在[{3}}博客文章以及有关CodeProject Factory Design Pattern in C++A C++ Object Factory的两篇文章中进行了讨论。

当然,对此也有一个答案: Factory Pattern in C++

答案 1 :(得分:1)

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 ] (); 并将其替换为等效的内容。例如,

switch

这允许运行时自定义和模块化。 &#34;案件的主体&#34;可以在不同的源文件中或在动态加载的模块中。

较小的更改是用类似但更安全的方式替换容易出错的case - CASE语句。我的safe_switch library提供break;而不需要std::unique_ptr< InformationElement >,这在您的示例中已被遗忘。

顺便说一句,看起来InformationElement *可能比{{1}}更合适。