我正在编写具有大量有向图辅助函数的程序,以便更深入地了解 C++。其中一个中心对象称为节点,它具有帮助计算节点之间的行进距离的成员函数。我试图更好地理解在 OOP 设计中使用 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 类型。我意识到我可以着手进行函数重载。但是,我觉得这太多余了,明显违反了 DRY 原则。如果我必须改变这个函数的工作方式,我必须在每次重载时改变它。所以我的直觉告诉我应该使用 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 与表示边权重的浮点类型相关联。
那么在这种情况下,模板的最佳或适当用法是什么?或者在这里使用模板甚至是正确的路径?我的班级设计可能一开始就有缺陷,而且不是很 C++'esk。非常感谢这里的任何反馈。