2016-06-13 2 views
2

Следует ли избегать круговой зависимости на графиках?Циклическая зависимость и графики

Например, consideer в класс вложение массив vertex объектов, каждый из которых имеет множество edge объектов, которые указывают на vertex.

Здесь vertex и edge имеют круговую зависимость. Это плохая идея ? Должен ли он и как его можно избежать?

+0

часто «край» будет использовать идентификаторы для каждой «вершины» и не использовать указатели для каждой «вершины». «Граф» будет содержать ребра, а также вершины. – vu1p3n0x

+0

@ vu1p3n0x: Как полезно использовать идентификаторы, а не указатели, за исключением избежания круговой зависимости? – servabat

+0

Все зависит от того, как будет использоваться ваш график. Если вам нужен объект «edge», который будет автономным и не привязан к самому графику, вам нужно использовать указатели на вершины. Однако, если ваш класс графа хранит вершины в 'vector' и поддерживает добавление вершин, вы не можете использовать указатели, потому что они могут перемещаться. – vu1p3n0x

ответ

2

Нет, не следует. Графики, которые имеют нетривиальные классы ребер и вершин, являются по существу с круговой зависимостью. Если edge практически пуст, вы можете просто сохранить матрицу смежности (т. Е. Существует ли ребро между заданными вершинами); если vertex пуст, вы можете сохранить и список ребер, который хранит число вершин (size_t) вместо указателя. Лучшей практикой является использование smart_ptr <> и weak_ptr <> для разрыва цепи. Последнее не является владеющим, таким образом:

  • Если ваш граф хранит вершин:
    • класс имеет vector< smart_ptr<vertex> >
    • vertex класс имеет vector< smart_ptr<edge> > m_out; и, возможно, vector< weak_ptr<edge> > m_in;
    • edge класс имеет weak_ptr<vertex> m_vertices[2]; (или лучше но m_from и m_to)
  • Если ваш граф магазинов края:
    • класс имеет vector< smart_ptr<edge> >
    • edge класс имеет smart_ptr<vertex> m_from; и weak_ptr<vertex> m_to;
    • vertex класс имеет vector< weak_ptr<edge> > m_out; и, возможно, vector< weak_ptr<edge> > m_in;

Если по какой-то причине (как widsom старшего :), стандарт кодирования и т. д.), вы не можете использовать s mart_ptr <> и weak_ptr <>, вы можете использовать ссылки вместо слабых указателей, которые обычно считаются не принадлежащими. Вместо smart_ptr <> вы можете использовать указатели - или почему бы не иметь членов, пока edge и vertex не являются базовыми классами. Stroustrup дополнительно рекомендует отмечать голые указатели, которые следует удалить при выходе с использованием owner<>. Если у вас его нет, вы можете определить no-op для него как template<typename T> using owner = T;.

Смежные вопросы