1

私は相互リンクされているいくつかの異なるタイプのクラスを持っています (それらには相互へのポインターが含まれています - それらのいくつかはポインターのベクトルです)、私はこの設計にかなり満足しています。しかし今、すべての構造のコピーを作成したいと思うようになり、新しいクラスのすべてのインスタンスのすべてのリンクを修正するのは非常に困難です。私はすでにすべての構造のコンテナ クラスを持っていますが、clone()メソッドを記述しようとすると非常に汚いコードになってしまい、満足できません。

この問題を解決するのに役立つような設計パターンがあるかどうかを知りたいです。

4

3 に答える 3

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 に答える