我在c ++中有一个名为InformationElement的类,它定义了以下信息元素框架结构:
< -Element ID-> < -Element Length->< -Variable Payload->
从这个类中继承了不同的派生类,例如:
每个派生类都有唯一的元素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插入一个独特的案例更好吗?
答案 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}}更合适。