我有几个不同类型的类是交叉链接的(它们包含指向彼此的指针——其中一些是指针向量),我对这种设计非常满意。但是现在到了一个地步,我想复制我的所有结构,并且很难更正新类的每个实例的所有链接。我已经为所有结构创建了一个容器类,但我编写clone()
方法的尝试仍然以非常脏的代码告终,我对它们并不满意。
我想知道是否有一种设计模式可以帮助解决这个问题。
我有几个不同类型的类是交叉链接的(它们包含指向彼此的指针——其中一些是指针向量),我对这种设计非常满意。但是现在到了一个地步,我想复制我的所有结构,并且很难更正新类的每个实例的所有链接。我已经为所有结构创建了一个容器类,但我编写clone()
方法的尝试仍然以非常脏的代码告终,我对它们并不满意。
我想知道是否有一种设计模式可以帮助解决这个问题。
一种可能对您有所帮助的解决方案(如果我从您相当模糊的描述中理解正确的话):
std::map<void*,void*>
应该做的工作,但也许你可以想出比丑陋更好的东西void*
)通常的方法是保留某种旧的到新指针的映射形式——在制作副本之前,请查阅映射以查看对象是否已被复制,如果是,则返回现有副本,否则,调用 clone()。
像这样的东西:
#include <unordered_map>
#include <vector>
typedef std::unordered_map<void *, void *> map_type;
template<typename T>
T *clone (T *ptr, map_type &m)
{
auto p = m.find (ptr);
if (p != m.end ())
return static_cast<T *> (p->second);
else
return ptr->clone (m);
}
struct S
{
int x;
std::vector<S *> v;
S *clone (map_type &m)
{
S *p = new S;
// this is important to happen before calling clone() on subobjects
m [this] = p;
p->x = x;
for (auto q: v)
p->v.push_back (::clone (q, m));
return p;
}
};
int
main ()
{
S *p = new S ();
p->x = 1;
S *q = new S ();
q->x = 2;
S *r = new S ();
r->x = 3;
p->v.push_back (p);
p->v.push_back (p);
p->v.push_back (q);
q->v.push_back (p);
q->v.push_back (r);
r->v.push_back (p);
map_type m;
S *x;
x = clone (p, m);
}
如果您可以将层次结构(子父关系)与链接一起施加,它可能会更清晰一些。然后您可以递归地进行克隆过程 - 让每个父母在克隆和更新引用的同时克隆其所有子项。
如果您在同一级别上具有关系(例如,对象是对等对象并且在圆圈中相互交叉引用),您可以人为地添加将克隆所有子级的父级,更新其自己的引用,然后使用新引用更新子级。
这将允许在不修改大部分代码的情况下缩放/添加新组件。