我正在尝试将一些代码从我的C ++模拟软件拆分到库中,因此可以更灵活地使用它。模拟基于Lattice
,由许多Node
组成,其中包含指向其Neighbor
的指针列表。虽然邻居也是节点,但我希望在*Node
指针周围有一个小的包装类,以便实现其他逻辑/字段(例如,bool is_neares_neighbor
左右。
我的类架构因此看起来像这样:
class Lattice {
private:
vector<Node> _nodes;
};
class Node {
private:
vector<Neighbor> _neighbors;
};
class Neighbor {
private:
Node * _node;
};
到目前为止,这么好。现在,我希望我的库能够处理所有与格相关的逻辑,但没有别的。但是,在某个项目中使用库时,这三个类(Lattice
,Node
,Neighbor
)将包含更多逻辑和字段。因此,用户应该能够从这些类继承并实现他/她的自定义内容,而库仍然处理所有必需的与格相关的逻辑。
建议的方法是什么?模板是否合适?在模板化的情况下,我的类层次结构将如下所示:
template<class N>
class Lattice {
private:
vector<N> _nodes;
};
template<class NN>
class Node {
private:
vector<NN> _neighbors;
};
template<class N>
class Neighbor {
private:
N * _node;
};
正如您所看到的,Node
和Neighbor
都需要知道彼此的类型,这是一个循环条件,我不知道如何处理这里。此外,整个库必须存在于头文件中。
如何在C ++世界中以最优雅的方式处理这些情况?
答案 0 :(得分:1)
我在想你希望模板类型是格子库不知道或不关心的“其他类型”。因此,不是让用户从Node派生,而是使用模板&lt; class t_data&gt;为你所有的课程。
你说自己,邻居是一个节点,所以你应该能够根据Node&lt; t_data&gt;来定义所有内容。
您还应该考虑如何构建晶格,以及如何返回有关它的信息。这是一个例子,我假设你通过让格子类创建节点来创建格子,并且可以选择在创建时将它们连接到现有节点。
#include <vector>
#include <memory>
template<class t_data>
class SetOfNodes;
template<class t_data>
class Node {
public:
Node(t_data value, SetOfNodes neighbors) : _data(value), _neighbors(neighbors) {}
is_nearest_neighbor(const Node &other){
// is other in _neighbors?
// is other the closest neighbor?
return false;
}
private:
t_data _data;
SetOfNodes _neighbors;
};
template<class t_data>
class SetOfNodes {
public:
std::vector<std::shared_ptr<Node<t_data>>> _nodes;
};
template<class t_data>
class Lattice {
public:
SetOfNodes get_all_nodes();
void create_new_node(SetOfNodes neighbors);
private:
SetOfNodes _nodes;
};
我真的不了解Neighbor,因为要么是Node,要么它涉及两个节点,所以我会单独留下它。
答案 1 :(得分:0)
我建议你使用复合/访客模式的组合:
当您想要扩展您无法控制的库(或类集)时,这是一种特别推荐的方法。根据我的理解,这是您希望用户能够做到的事情之一。