我有几种不同类型的交叉链接类(它们包含指向彼此的指针 - 其中一些是指针的向量),我对这个设计非常满意。但是现在我想要复制我的所有结构并且很难纠正新类的每个实例的所有链接。我已经有了一个容器类用于所有结构,但我编写clone()
方法的尝试仍然是非常脏的代码,我对它们不满意。
我想知道是否有一种设计模式可以帮助解决这个问题。
答案 0 :(得分:1)
一个可能对您有帮助的解决方案(如果我从您相当含糊的描述中正确理解的话):
std::map<void*,void*>
这样的东西应该可以完成这项工作,但也许你可以提出比丑陋{{{}更好的东西。 1}})答案 1 :(得分:1)
通常的方法是保留某种旧映射表单到新指针 - 在复制之前,查阅映射以查看对象是否已被复制,如果是,则返回现有副本,否则,调用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);
}
答案 2 :(得分:0)
如果您可以将层次结构(子父关系)与链接一起强加,那可能会更清晰一些。然后,您可以递归地接近克隆过程 - 让每个父母在克隆和更新引用时克隆其所有子项。
如果您在同一级别上有关系(比如,对象是对等的并且在圆圈中相互交叉引用),您可以人为地添加将克隆所有子项的父项,更新其自己的引用,然后使用new更新子项引用。
这将允许在不修改大部分代码的情况下扩展/添加新组件。