![]() |
1
4
我认为您要问的是如何将对象创建代码与对象本身保持在一起。 这通常是我所做的。它假定有一些键为您提供了一个类型(int标记、字符串等)。我创建了一个类,它有一个键到工厂函数的映射,以及一个注册函数,它获取一个键和工厂函数并将其添加到映射中。还有一个创建函数,它获取一个键,在地图中查找它,调用工厂函数,并返回创建的对象。例如,取一个int键和一个包含剩余信息的流来构建对象。我还没有测试过,甚至没有编译过这段代码,但是它应该给你一个想法。
然后,在从子对象派生的每个类中,使用适当的键和工厂方法调用register()方法。 要创建对象,您只需要这样做:
|
![]() |
3
3
我建议你读一下 C++ FAQ Lite questions concerning serialisation and unserialisation . 其中有很多细节,我无法在我的答案中简单总结,但这些常见问题解答确实包括创建仅在运行时才知道类型的对象。 特别地: 不过,在最基本的层面上,您可以实现一个类似于以下内容的工厂:
|
![]() |
4
0
阅读经典 Gang Of Four aka GOF . 考虑[本网站[( http://www.dofactory.com/Patterns/PatternAbstract.aspx )对于工厂和其他C模式。 |
![]() |
5
0
除非我遗漏了一些东西,否则您不需要静态类型转换来创建一个运行时类型是您应该从工厂返回的类型的子类的对象,然后以多态方式使用它:
在您提到的问题中,op所讨论的模式是从某个地方获取一个super*,然后通过检查rtti并为程序员已知的所有子类使用if/else子句将其转换为运行时类型。这与“创建对象后,我使用它的多态性”完全相反。 理论上,我对反序列化的首选方法是责任链:编写能够查看序列化数据(包括类型头)并自行决定是否可以从中构造对象的工厂。为了提高效率,让工厂注册他们感兴趣的类型,这样他们就不会查看每个传入对象,但这里我忽略了这一点:
在实践中,我经常会编写一个大的开关,就像这样,只使用枚举类型、一些命名常量,或者在构造之后调用一个虚拟反序列化方法:
|
![]() |
6
0
工厂模式的基本操作是将标识符映射到特定类型的(通常是新的)实例,其中类型依赖于标识符的某些属性。如果你不这样做,那它就不是一个工厂。其他一切都是品味问题(即性能、可维护性、可扩展性等)。 |