2

我正在设计一个必须本质上支持操作历史记录(撤消/重做)和序列化的系统。它包含各种实体,许多实体以图的形式链接。

我想通过让操作了解对象的创建、销毁和链接来自动化大部分历史记录工作。我面临的问题如下:

假设我创建对象A,然后创建对象B,然后链接AB。这是三个动作。现在撤消所有操作,操作将移至“重做”列表。现在,重新做一遍。这意味着创建了一个 的 A对象,创建了一个新的 B对象。为了重做链接操作,我需要知道作用于 AB对象的“链接”动作现在将应用于 的 AB对象。

一个简单的重定位表就可以解决问题;创建新对象时,只需将旧地址映射到新地址,并使用它来解释历史日志中的任何链接关系。问题是,如果涉及多重继承会发生什么?也就是说,链接可能引用指向 A 基址的指针不是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我需要一种方法来知道它们都标识同一个对象,原因如上所述(执行/撤消操作可能会在新位置重新创建对象,因此必须更新所有指向它的指针。)

4

0 回答 0