我正在设计一个必须内在支持动作历史(撤消/重做)和序列化的系统。它包含各种实体,许多实体链接为图形。
我希望通过让对象了解对象创建,销毁和链接来自动化大多数历史记录日志工作。我面临的问题如下:
假设我创建了对象 A ,然后对象 B ,然后链接 A 和 B 。这是三个动作。现在撤消所有内容,操作将移至“重做”列表。现在,重做一切。这意味着创建了 new A 对象,并创建了 new B 对象。要重做链接操作,我需要知道现在要应用旧 A 和 B 对象的“链接”操作到新 A 和 B 对象。
一个简单的重定位表可以解决问题;在创建新对象时,只需将旧地址映射到新地址,并使用它来解释历史日志中的任何链接关系。问题是,如果涉及多重继承会发生什么?也就是说,链接可能指向 A 的 base 指针,而不是 A 本身,因此地址可能与搬迁表。
系统必须在内存中处理数百GB,因此出于性能原因,我宁愿不要在内部丢弃所有指针并切换到全局唯一ID并始终执行表查找。抛出所有内容的虚拟基类也是不可取的,因为有些类型非常轻量级。
问题是,除了我提到的两个替代方案之外,是否可以通过指向(可能是多个)基类之一的指针来唯一地标识对象?我应该放弃自动化并为每种类型编写专门的代码吗?
修改
也许我对这个冗长的解释并不清楚。以下是展示问题的简单示例:
#include <iostream>
using namespace std;
struct A { int x; };
struct B { int y; };
struct AB : A, B { int z; };
int main()
{
AB ab;
AB* pab = &ab;
A* pa = &ab;
B* pb = &ab;
cout << "pab: " << pab << endl;
cout << "pa: " << pa << endl;
cout << "pb: " << pb << endl;
}
一个可能的输出是:
pab: 0x7fff30b6a400
pa: 0x7fff30b6a400
pb: 0x7fff30b6a404
如您所见,pb
的值与pab
不同,即使它们来自同一个对象。我需要一种方法来知道它们都识别相同的对象,原因如上所述(do / undo操作可能会在新的位置重新创建对象,因此所有指向它的指针都必须更新。)