序列化撤消队列 [英] Serializing the undo queue

查看:98
本文介绍了序列化撤消队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想序列化和反序列化撤消队列.我有交易的基类.所有子类均在m_undo双端队列中按其基类列出.我希望能够从基类中调用专门的输入/输出函数.我可以通过在基类中使用虚函数并在子类中重写它,然后将传递的事务指针参数转换为其子类来轻松完成写操作.

但是我看不到一种简单的读入解决方案.我能想到的一个解决方案是,像我的顾问教我(以及我自己做的一些大惊小怪的事情)来对文档的工厂进行序列化.

1.全局序列化和反序列化功能,用于实现下面的所有内容
2.一个将元素指针映射到bool(true)的extern SerializeMap和一个将元素指针映射到其id的外部DeserializeMap.这些地图是全球性的.
3.一个入口"类(全局),用于容纳一个静态反序列化功能映射,该映射将注册类名称映射到指向该注册类的指针反序列化"函数的指针,以及一个构造函数,用于初始化静态反序列化函数map
4.一个声明宏,它将声明类的实例静态地嵌入到注册类中,并且还声明了一个静态的反序列化函数.它还具有内联虚拟istream和ostream功能.
5.一个定义宏,该宏使用映射到其反序列化功能的地址的注册类的名称来初始化注册类的静态条目类.最后,反序列化函数的定义神奇地扩展了注册类的名称,以便在运行时可以创建该子类的新实例.该函数采用id参数,然后可以由地图中的新对象分配该参数.然后读取该实例.

宏可以接受一个类名变量(如字符串),并用运算符#对其进行字符串化,这很整洁,然后在扩展该宏时,该名称便会出现并充当使用该子变量的所有子类的代码中的类名.宏.然后我们写出并读入xml中的名称,并在其中添加一个"C",然后在函数映射中找到它以调用正确的反序列化函数.

我认为我可能可以从上方省略交易的标识符部分,因为所有交易都会有所不同.我们在doc元素版本中使用它,因为某些元素由许多不同的事物指向.

一个主要的问题是,如果我添加了新工厂,我将引入两个新的静态映射,它们将在其中依赖于带有两个静态映射的doc工厂的对象进行序列化.令我担心的是,但这可能是可以的,因为所有的注册和初始化都在编译时发生,然后在运行时使用它们.还是建议将交易作为doc元素子类化,然后将其添加到已经存在的工厂中;交易应该是doc对象吗?

另一个问题是,在我定义静态函数映射之后,我不得不将所有定义宏放在一个.ccp文件中的一个位置,因为我还没有找到更好的方法来执行该宏.初始化顺序正确.由于将有成百上千的交易,所以看起来并不好.

我的问题是,是否有一种更好,更简单,更安全的方法来从其基类(事务)列表中读取不同的子类对象(多样化交易)?

我能想到的另一种解决方案是有一个开关,用于处理读入的名称,然后适当地强制转换事务,但这听起来并不有趣,但毕竟还是更好.

有什么好招吗?等不及了.

I would like to serialize and deserialize the undo queue. I have a base class for transactions. All of the subclasses are listed by their base class in the m_undo deque. I want to be able to call the specialized input/output functions from the base class. I can do this easily for writing out by using a virtual function in the base and overriding it in the subclasses and then cast the passed transaction pointer parameter to its subclass.

But I can''t see an easy solution for reading in. One solution I can think of is to do like my consultant taught me (along with some fussing on my own) for my document''s factory serialization.

1. Global Serialize and Deserialize functions for implementing everything below
2. An extern SerializeMap that maps an element pointer to a bool (true) and an extern DeserializeMap that maps an element pointer to its id. The maps are global.
3. An "entry" class (global) to house a static deserialize funtion map that maps a registering class name to a pointer to the registering class'' deserialize function, and a constructor that initializes the static deserialize function map
4. A declaration macro that embeds an instance of the entry class statically into registering classes and also declares a static deserialize function. It also has inline virtual istream and ostream functions.
5. A definition macro that initializes the static entry class of the registering class with the registering class'' name mapped to the address of its deserialize funtion. Finally the definition for the deserialize function magically expands the registering class'' name so that at run time it can create a new instance of the subclass. The function takes an id parameter that can then be assigned to by the new object in the map. The instance is then read in.

It''s neat that the macro can take a class name variable like a string, stringize it with operator #, and then when the macro is expanded the name appears and acts as the class name in the code of all the subclasses that use the macro. Then we write out and read in the name as in xml and add a "C" to it and find it in the function map to call the correct deserialize function.

I think I might be able to leave out the identifier part from above for the transactions since all of the transactions would be different. We use it in the doc element version because some elements are pointed to by many different things.

One major concern is that if I added the new factory, I''d be introducing two new static maps, and they''d be serializing objects within them that rely on the doc factory with its two static maps. It worries me but maybe it would be OK since all of the registering and initialization happens at compile time and then the usage of them happens at run time. Or would you suggest just subclassing the transaction as a doc element and adding them to the factory already in place; should a transaction be a doc object?

Another problem is that I''d have to put all of the definition macros in one place, in one .ccp file, after the definition of the static function map since I haven''t found a better way to do it to enforce the initialization order correctly. Since there will be hundreds if not thousands of transactions, it doesn''t seem great.

My question is, is there a better, simpler, and safer way to to this, read in varying subclassed objects (diverse transactions) objects from a list of their base class (transaction)?

Another solution I can think of is to have a switch that handles the name read in and then casts the transaction appropriately but that doesn''t sound like much fun but maybe it is better after all.

Have any good tricks for this? Can''t wait.

推荐答案

布莱恩,

恕我直言,使用 Boost序列化 [
Hi Brian,

IMHO using Boost Serialization[^] should be simpler and easier to maintain than a home cooked solution, with not much more initial investment.

I don''t foresee any problem with std::iostream as the boost::serialization::archive classes use them internally.

The current (1.44) library does not know about C++0x std::shared_ptr, but the source for serializing boost::shared_ptr is not that difficult to transpose to a custom std::shared_ptr serialization.

cheers,
AR


这篇关于序列化撤消队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆