Компартментализация и дизайн классов в C ++ - PullRequest
2 голосов
/ 20 декабря 2010

В свободное время я беру код, написанный для различных целей, и переношу его на другие языки, чтобы посмотреть, что там. В настоящее время я беру алгоритм генетической раскраски графов, изначально написанный на Java, и пытаюсь привести его к C ++.

Произвольная структура данных, которую я использую для этой задачи, имеет несколько классов. В Java это не было для меня проблемой, потому что я некоторое время подвергался этому. Структура графа была создана только один раз, и ей было присвоено Colouring. Colouring (в частности, поиск наиболее оптимального) было реальным смыслом кода. У меня может быть класс Graph с внутренними классами, такими как, например, Node и Edge, или у меня может быть пакет graph с классами Graph, Node, Edge и т. Д.

Первый случай, приведенный выше, вполне может подойти для моей идеи C ++. В основном файле * .cpp могут быть определены классы Node, Graph, Edge. Но это, кажется, действительно упускает смысл C ++, из того, что я могу сказать. Я просто беру то, что я написал на Java, и заставляю это в C ++, добавляя деструкторы, где это уместно, и превращая ссылки на объекты в указатели. Я еще не думаю в C ++. Несут ли эти классы разделение на отдельные файлы * .cpp? Должны ли они быть отделены, а затем скомпилированы как библиотека для использования в основной программе? Что мне действительно нужно, так это какие-то хорошие ресурсы или надуманные примеры (или даже практические правила), чтобы сказать, в программировании на C ++, какие существуют различные варианты, и когда стоит подумать об одном над другим?


РЕДАКТИРОВАТЬ: @Pawel Zubrycki попросил меня привести пример кода. Я не собираюсь этого делать, потому что каждый компонент довольно тривиален - он обычно имеет ссылку на следующую вещь и некоторые методы get / set. Я, однако, опишу это.

По сути, это список случаев. Есть некоторые ненужные применения классов, названных ...Pointer - они были результатом буквального перевода диаграммы, впервые использованной для объяснения мне списков заболеваемости.

Существует класс контейнера VertexList, который содержит элемент head VertexPointer и методы для добавления новых объектов VertexPointer (добавление его в граф, но не подключение его к каким-либо другим узлам, что позволяет выполнять поиск в поиск несвязанных графиков), простой поиск индексов для объектов Vertex и т. д. Каждый VertexPointer имеет объект Vertex, а также VertexPointer next; и все эти удобные hasNext() методы, которые вы можете ожидать , У Vertex также есть связанный ConnectionList

То же самое дублируется для EdgeList, EdgePointer и Edge, за исключением того, что Edge связан с двумя Connection объектами.

ConnectionList и Connection: ConnectionList, имитирующие VertexList или EdgeList, имеющие Connection head; и все те удобные методы, которые вы можете ожидать, например addConnection(). С Connection связан Edge, а также некоторые Connection next;

Это позволяет нам легко получить связанные компоненты любой одной точки на графике и иметь произвольное количество соединений.


Это кажется чрезмерно сложным, но та же функциональность может быть дублирована с некоторыми LinkedList из Vertex объектов, LinkedList из Edge объектов и несколькими LinkedList из Connection предметов. Объекты LinkedList из Vertex позволяют нам выполнять итерации по всем вершинам для исчерпывающего поиска по вершинам, и то же самое относится и к ребрам. LinkedList объекты Connection позволяют нам быстро перемещаться к любым связанным вершинам и произвольно добавлять или соединять в графе. Этот шаг по сложности был добавлен, чтобы справиться со сложностью оценки определенной раскраски графа (взвешенные ребра, быстрый обход локальных подграфов и т. Д.)

1 Ответ

2 голосов
/ 20 декабря 2010

Если у вас есть классы, такие как Node, Graph и Edge, и их реализация не слишком велика, имеет смысл определить их в одном и том же файле .cpp. В конце концов, они предназначены для совместного использования.

В C ++ такой пакет называется компонентом. Обычно более разумно думать о компонентах, чем о классах, поскольку C ++ - это не только язык ООП, а классы не всегда являются предпочтительным способом действий.

Если вы хотите узнать больше о предпочтительном способе организации кода на C ++, я рекомендую Large Scale C ++ Software Design .

Кстати: создание библиотеки из этих классов действительно кажется излишним.

...