у меня есть следующие иерархии классов для графов:вопрос дизайна иерархии наследования классов
typedef vector<int> ArrayI;
typedef vector<Array<long>> Mat2DB;
typedef vector<ArrayI> adjList;
class baseGraph {
int nodes;
ArrayI degree;
//some member functions.
}
class matGraph: public baseGraph {
Mat2DB matrix;
//member functions.
}
class lMatGraph: public matGraph {
ArrayI labels;
//member functions.
}
class listGraph: public baseGraph {
adjList list;
//member functions.
}
class lListGraph: public listGraph {
ArrayI labels;
//member functions.
}
Теперь в этом классе у меня есть много других функций, в основном виртуальных, так что, когда я вызвать правильную функцию при использовании указатель базового класса.
Например, у меня есть функция sssp(int node)
, которая реализует кратчайший путь с одним источником. Реализация различна для class matGraph
и class listGraph
, которые представляют собой представление матрицы смежности и представление списка смежности соответственно графиков. Теперь не нужно изменить определение для меченого версии этих графиков, так что я не определяю эти функции снова в lListGraph
и lMatGraph
Теперь единственная проблема, я Хавин это с setLabel(const ArratI &)
в lListGraph
и lMatGraph
классов. Мне нужно, чтобы эта функция была виртуальной, чтобы она вызывалась через указатель базового класса, но в то же время у меня нет ничего такого, как метки для классов matGraph
и listGraph
.
Я не знаю, правильна ли моя иерархия дизайна или нет, но она показалась мне интуитивной. Поэтому любые комментарии по этому вопросу были бы хорошими. Что я могу сделать с помощью функции setLabel
. Хорошо ли иметь такую функцию (для меня это выглядит как обходной путь, поэтому этот вопрос), или мне нужно пересмотреть мою иерархию классов.
P.S .: Я также был бы рад, если есть некоторые книги, из которых я могу практиковать вопросы дизайна, подобные этим. Я натыкаюсь на эту делимму и не знаю, что с ними делать.
EDIT:
Использование класса графа используется в другом классе clustering
, где я есть член baseGraph *graph
т.е.
class clustering {
baseGraph *graph;
}
Я хранить указатель на базовый класс здесь, так что я могу использовать различные алгоритмы (реализованы как функции) от class graph
. Для класса кластеризации он снова зависит от того, какой тип графика я хочу использовать.
Помните, что 'vector' специализируется на отличном от всех других стандартных контейнерах (возможно, вы это предполагали). –
@MarkB В моей оригинальной реализации я использую 'vector' для моделирования взвешенных графиков, так что это нормально, но рад узнать разницу. Набрав вопрос, я решил сделать иерархию простой. Я отредактирую вопрос. –
Должен ли ярлык меняться несколько раз во время выполнения? Или он останется постоянным для жизни объекта? –