设计我的程序以避免必须从基类转换为派生类

时间:2010-11-09 14:40:49

标签: c++ design-patterns polymorphism

好吧,我似乎要求从基础到派生的正向投射,我认为这可能是一个设计问题所以我会解释我在做什么,你可以告诉我我需要改变什么。 XML文件定义了一堆类似的对象。它们共享相同的基类。 main函数在基类DoWork()中定义,它是虚函数。

我的程序加载XML文件并创建派生类并将它们分配给基类类型的向量。

程序运作的一切都很棒。我可以迭代向量并调用DoWork();

现在,我添加了一个GUI层,以便您可以修改对象并写回XML文件。所以,现在我的GUI代码可以访问基类指针的向量。但是,这并不好,因为我需要派生类的信息,所以我可以写出XML文件。这是动态铸造的唯一解决方案吗?我能以某种方式改变设计吗?我知道从基地到派生的铸造是不受欢迎的。

编辑:我的GUI需要显示派生类所具有的信息。仅仅拥有序列化类是不够的。

6 个答案:

答案 0 :(得分:4)

你可以添加例如每个类的虚拟serialize方法,以便输出循环可以遍历向量,并在每个元素的基指针上调用(*it)->serialize()

答案 1 :(得分:3)

您可以在此处采用两种不同的方法。第一个是提供一个生成与元素对应的XML的虚方法。

第二种方法是提供访问者界面:基本上,您定义了一个接受visitor类型的虚拟方法。将在层次结构的每个级别使用当前对象调用访问者类型,从而生成一种双重调度机制。这样,虚拟调度将解析为派生最多的对象,这将调用访问者对象自行序列化。

第一种方法更简单,而第二种方法的优点是层次结构中的每个对象与实际的序列化格式之间的耦合更松散。也就是说,您可以生成可以序列化为不同格式的不同访问者,而无需修改当前层次结构中的代码。

答案 2 :(得分:1)

您可以在基类中定义一个方法,将对象打印到XML,然后让所有派生类提供它们自己的实现。基本上,您将委托打印到派生类。

编辑:或者更一般地说,遵循Oli的建议并为您的基类编写一个serialize()方法,该方法返回该对象的重要数据元素的易于消化的集合(例如,键值对列表)。然后,您的主程序可以遍历每个对象的序列化表单,并决定如何处理它。

答案 3 :(得分:1)

  1. 发布一个小代码示例 -

  2. 听起来像基类需要一个虚拟的WriteXML() - 此时只是猜测

答案 4 :(得分:0)

在基类中实现一个派生类可以覆盖的函数,以显示写出Xml所需的信息,或者让对象本身保持为Xml。这两种解决方案都不需要您知道它是什么。

答案 5 :(得分:0)

如果在基类中定义了相同的行为,您需要使用它来获取派生类中的数据,那么您可以将所有对象视为相同。对于以前没有此行为的派生类,您可以让它们以静默方式失败。看一下复合设计模式的意图。