C++ directed graph node with template implementation
I am writing program which has a multitude of Directed Graph helper
functions in order to gain a deeper understanding of C++. One of the
central objects is called a Node which has member functions to help with
calculating travel distance between nodes. I am trying to gain a better
understanding of using C++ templates in OOP design.
Here is a quick snapshot of the Node class
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
As I build this class to include more functionality, I find myself
struggling with how to make my functions more adaptable. For instance,
look at the findTravelDistance functions.
What I would like to do is have the return type representing weight be
type agnostic and the ordered map data structure's value to be type
agnostic. As it is currently implemented, a user can only declare a type
int for the weight. I realize I could embark upon function overloading.
But, I feel this would be too redundant and an obvious violation of the
DRY principle. If I were to have to change how this function works, I
would have to change it for every overload. So my gut instinct tells me I
should use C++ templates. Since I am new to templates, I am struggling
with where to declare it. If I make my find functions template functions
and just return the generic type..
template<class T>
T findTravelDistance(std::queue<Node *> * const & nodeRoute) const;
That will solve my problem there. But, it doesn't fix the issue where the
underlying map data structure representing edges can only hold ints. My
next thought was to declared a class template..
template<class T>
class Node { ... }
But this also seemed odd to me. This would mean declaration and
initialization would look something like
Node<float> * n = new Node("N");
If I were a user of my program, I would not immediately associate Node
with the float type representing edge weights.
So what is the best or appropriate usage of a template in this case? Or is
using a template even the correct path here? It is possible my class
design is flawed to begin with and not very C++'esk. Any feedback here is
much appreciated.
No comments:
Post a Comment