oop — узел ориентированного графа C ++ с реализацией шаблона

Я пишу программу, которая имеет множество вспомогательных функций Directed Graph для более глубокого понимания C ++. Один из центральных объектов называется узлом, который имеет функции-члены, помогающие рассчитать расстояние перемещения между узлами. Я пытаюсь лучше понять использование шаблонов C ++ в ООП-дизайне.

Вот быстрый снимок класса Node

class Node {

friend void swap(Node & first, Node & second) {
using std::swap;
swap(first.name, second.name);
}

public:

Node(std::string val);

Node(const Node & copy);

Node & operator = (Node copy) {

swap(*this, copy);
return *this;

}

bool operator < (Node & rhs) const {
return (size < rhs.size);
}

bool operator > (Node & rhs) const {
return (size > rhs.size);
}

bool insertEdge(Node * dest, int distToNode);

// I'd like for this return type to not be tied to an int
// Especially if weights were represented as floats or doubles
int findTravelDistance(Node * const & toNode) const;
int findTravelDistance(std::queue<Node *> * const & nodeRoute) const;

// Mutators
void setNodeName(const std::string nameToSet);
std::string getNodeName() const;

void setNodeSize(const int size);
int getNodeSize() const;

// Misc
void toString() const;

// Constants
static const bool ALLOW_CIRCULAR;

~Node();

protected:private:
int size;
std::string name;
// Here int represents the weight of the edge. I would like it to be able to be
// declared as an int, float, long, or double etc...
std::map<Node *, int> * travelEdges;

}; // end class

} // end namespace

Когда я создаю этот класс, чтобы включить больше функциональности, я сталкиваюсь с тем, как сделать свои функции более адаптируемыми. Например, посмотрите на функции findTravelDistance.

Я хотел бы, чтобы возвращаемый тип, представляющий вес, был независимым от типа, а значение упорядоченной структуры данных карты было бы независимым от типа. Поскольку это в настоящее время реализовано, пользователь может только объявить тип int для веса. Я понимаю, что мог бы перегружать функции. Но я чувствую, что это было бы слишком излишним и явным нарушением принципа СУХОЙ. Если бы мне пришлось изменить работу этой функции, мне пришлось бы менять ее при каждой перегрузке. Мой инстинкт подсказывает мне, что я должен использовать шаблоны C ++. Поскольку я новичок в шаблонах, я борюсь с тем, где его объявить. Если я сделаю свой поиск функций шаблонных функций и просто верну универсальный тип ..

template<class T>
T findTravelDistance(std::queue<Node *> * const & nodeRoute) const;

Это решит мою проблему там. Но это не решает проблему, когда базовая структура данных карты, представляющая ребра, может содержать только целые числа. Моей следующей мыслью было объявить шаблон класса ..

template<class T>
class Node { ... }

Но это также показалось мне странным. Это будет означать, что объявление и инициализация будут выглядеть примерно так:

Node<float> * n = new Node<float>("N");

Если бы я был пользователем моей программы, я бы не сразу связывал Node с типом float, представляющим веса ребер.

Итак, как лучше или лучше использовать шаблон в этом случае? Или использует шаблон даже правильный путь здесь? Вполне возможно, что мой дизайн класса с самого начала имеет недостатки и не очень в C ++. Любая обратная связь здесь высоко ценится.

1

Решение

Это очень чистый код :). Добро пожаловать в C ++!

Я считаю, что вы хотите сделать, это использовать переменную шаблона для удержания веса ребра. Как насчет чего-то вроде следующего:

using std::swap;
template<class Distance>
class Node {

friend void swap(Node & first, Node & second) {
swap(first.name, second.name);
}
public:

Node(std::string val);

Node(const Node & copy);

Node & operator = (Node copy) {

swap(*this, copy);
return *this;

}

bool operator < (Node & rhs) const {
return (size < rhs.size);
}

bool operator > (Node & rhs) const {
return (size > rhs.size);
}

bool insertEdge(Node * dest, Distance distToNode);

// I'd like for this return type to not be tied to an int
// Especially if weights were represented as floats or doubles
Distance findTravelDistance(Node * const & toNode) const;
Distance findTravelDistance(std::queue<Node *> * const & nodeRoute) const;

// Mutators
void setNodeName(const std::string nameToSet);
std::string getNodeName() const;

void setNodeSize(const Distance size);
int getNodeSize() const;

// Misc
void toString() const;

// Constants
static const bool ALLOW_CIRCULAR;

~Node();

private:
int size;
std::string name;
std::map<Node *, Distance> * travelEdges;

}; // end class

В качестве бонуса я переместил ваши объявления об использовании в начало класса. Обычно они идут вверху файла. Вам также может быть полезно взглянуть на Священное Писание — FAQ по Parashift C ++, в частности раздел о правильности. Например, ваши методы сравнения должны иметь const Node& параметры.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]