1

我有几个不同类型的类是交叉链接的(它们包含指向彼此的指针——其中一些是指针向量),我对这种设计非常满意。但是现在到了一个地步,我想复制我的所有结构,并且很难更正新类的每个实例的所有链接。我已经为所有结构创建了一个容器类,但我编写clone()方法的尝试仍然以非常脏的代码告终,我对它们并不满意。

我想知道是否有一种设计模式可以帮助解决这个问题。

4

3 回答 3

1

一种可能对您有所帮助的解决方案(如果我从您相当模糊的描述中理解正确的话):

  1. 创建所有对象的克隆(现在,只需将所有指针复制到仍指向原始对象的新对象)
  2. 在这样做的同时,跟踪哪个对象是某种字典中哪个对象的克隆(类似std::map<void*,void*>应该做的工作,但也许你可以想出比丑陋更好的东西void*
  3. 遍历所有新对象并通过存储在字典中的值重定向所有指针
于 2013-08-06T14:26:54.163 回答
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);
}
于 2013-08-06T14:49:40.890 回答
0

如果您可以将层次结构(子父关系)与链接一起施加,它可能会更清晰一些。然后您可以递归地进行克隆过程 - 让每个父母在克隆和更新引用的同时克隆其所有子项。

如果您在同一级别上具有关系(例如,对象是对等对象并且在圆圈中相互交叉引用),您可以人为地添加将克隆所有子级的父级,更新其自己的引用,然后使用新引用更新子级。

这将允许在不修改大部分代码的情况下缩放/添加新组件。

于 2013-08-06T14:50:10.370 回答