gpt4 book ai didi

具有模板实现的 C++ 有向图节点

转载 作者:太空宇宙 更新时间:2023-11-04 11:51:23 25 4
gpt4 key购买 nike

我正在编写具有大量定向图辅助函数的程序,以便更深入地了解 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;

那将解决我的问题。但是,它并没有解决表示边的底层 map 数据结构只能保存整数的问题。我的下一个想法是声明一个类模板..

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

但这对我来说也很奇怪。这意味着声明和初始化看起来像

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

如果我是我的程序的用户,我不会立即将 Node 与表示边权重的 float 类型相关联。

那么在这种情况下模板的最佳或适当用法是什么?或者在这里使用模板甚至是正确的路径?有可能我的类设计一开始就有缺陷,而且不是很符合 C++ 的要求。非常感谢此处的任何反馈。

最佳答案

这是非常干净的代码:)。欢迎使用 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

作为奖励,我已将您的 using 声明移至类的顶部。通常这些位于文件的顶部。您也可能会从 Parashift C++ FAQ 的圣典中受益,尤其是 section on const correctness。 .例如,您的比较器方法应该具有 const Node& 参数。

关于具有模板实现的 C++ 有向图节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18094239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com