Как стать автором
Обновить

Комментарии 6

Интересно, спасибо. Однако, не могу удержаться от того, чтобы оставить здесь пару рекомендаций.

При просмотре кода бросилось в глаза использование оператора new (второй фрагмент, класс Vertice) - подумал, что, если рассматривать этот фрагмент автономно, он может быть правильным только при использовании какой-либо библиотеки сборки мусора. Однако, потом нашёл разъяснение в этой фразе:

"Здесь ничего сложного, но нужно помнить, что ребра создаются в классе вершин, а значит они должны и удаляться там же."

Послушайте, ничего помнить не нужно было бы, если бы вы пользовались не C указателем на ребро, а std::unique_ptr - и неявный автоматический деструктор, не удлинняя кода, избавил бы от забот; код был бы правилен без дополнительный пояснений о том, что кое-что важное опущено и что о чём-то нужно помнить. Вместо "сырого" new рекомендуется использовать std::make_unique - и воспросов в голове читателя не возникает, всё понятно. Явное использование delete становится ненужным, код упрощается.

Перескакиваю в конец, к breadthPassCommon - здесь история с тем, кто чем владеет, более запутанная. Visitor передаётся как сырой C указатель, в конце функции выясняется, что владение этим объектом тоже передано (вызывается delete, и ещё владение отслеживается хитрой логикой с флагом visitotPassed)! Использование std::unque_ptr здесь тоже бы выручило, сделало бы код менее запутанным, легче читаемым и поддерживаемым, хитрая логика и флаги были бы заменены перемещением std::unique_ptr (явно указывающим на перемещение владения).

Пожалуйста также, обратите внимание на синтаксис range loop ( for (auto&& edge : *vertice->getEdges()) ). Я лично стараюсь указатели использовать как можно реже, помогает в долгой перспективе.

unique_ptr в Vertice использовать нельзя, тк на ребро может ссылаться 2 вершины, значит нужно использовать shared_ptr, это как минимум дополнительный расход на переменную для подсчета ссылок. Я предпочел сэкономить. Логика класса очень простая, получить утечку памяти нереально
В breadthPassCommon использование unique_ptr действительно позволило бы избавиться от явного delete, но владение все равно пришлось бы отслеживать, только вместо visitotPassed пришлось бы отслеживать пустой unique_ptr или нет. Но в целом да, стало бы, пожалуй чуть аккуратнее.
Про range loop не понял

Раньше у вас было написано:


Хочу рассказать об одном интересном решении для работы с небольшими графами (несколько сотен или тысяч вершин с несколькими ребрами каждый)

Мизерные графы, а экономите на спичках.


дополнительный расход на переменную для подсчета ссылок

Такая реализация приводит к тому, что впустую расходуется указатель у ориентированных ребер, но сэкономить, к сожалению, не получится

Нет, ну вы серьёзно? Графы могут хранить в свойствах рёбер и вершин кучу данных, а вы на указателях экономите.

Могут, а могут и по int в ребрах и вершинах хранить. А еще могут быть миллионы маленьких графов. Экономить я в итоге не стал, о чем в статье и написано, но порассуждать никогда не бывает лишним

Про range loop можно прочитать, например, здесь: https://docs.microsoft.com/ru-ru/cpp/cpp/range-based-for-statement-cpp?view=msvc-160 - этот синтаксис более удобен в большинстве случаев при итерировании по контейнерам.

Вершина графа — не vertice, а vertex. Это множественное число vertices.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации