繁体   English   中英

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

[英]C++ directed graph node with template implementation

我正在编写具有大量“有向图”助手功能的程序,以便对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与表示边缘权重的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声明移到了类的顶部。 通常,这些文件位于文件的顶部。 您也可以从Parapara C ++ FAQ的圣经中受益,尤其是有关const正确性部分 例如,您的比较器方法应具有const Node&参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM