我正在用C ++编写自己的模板化Graph
类实现,所以我也在实现模板化的Vertex
和Edge
类。因此,实现必须在它们各自的头文件内,而不是在单独的.cpp
文件中。 (最佳答案here对我不起作用)
我的Vertex
类存储邻域的邻接列表,作为vector
的{{1}},Edge
类存储指向源和目标的指针{{1 s以及边缘的重量。
由于Edge
仅存储指向Vertex
的指针,因此在Edge
中转发声明Vertex
类就足够了。然后我可以在Vertex
的顶部Edge.h
。
这是解决#include "Edge.h"
和Vertex.h
类的共同依赖关系的最佳方法吗?用户必须Vertex
这两个文件才能使用其中任何一个(即Edge
)。
如果用户想要使用#include
而不必明确包含Graph.h
,反之亦然,该怎么办?我应该在另一个内部转发声明和Vertex
吗?
或者我应该在同一个头文件中实现它们吗?
如果有的话,STL中是否解决了这个问题?
这就是我现在所拥有的:
Edge.h:
Edge.h
Vertex.h:
#include
答案 0 :(得分:0)
如果用户想要使用Vertex而不必明确包含Edge.h,反之亦然,该怎么办?
由于您首先要讨论的是设计Graph
课程,因此在内部中包含两个标题并没有什么不妥。然后,用户只需#include "graph.h"
(或任何您称之为文件的内容),而不是真正考虑它是如何在较低级别设计的。
话虽如此 - 如果你想让你的班级按照现在的方式设计 - 你的解决方案是个好主意。但是,正如评论中已经提到的那样,Vertex不需要拥有它的边缘。也许你应该考虑一个不同的结构:
template<typename vertexType, typename edgeType>
class graph{
std::map<std::pair<vertexType,vertexType>, edgeType>;
};
请记住,使用此设计,特定方法的编写可能会稍微复杂一些(可能会慢一点)。但是 - 你最终会在这个过程中使用更少的内存。根据您真正想要实现的目标(小尺寸或快速工作),您最终可能会使用不同的图形结构。
答案 1 :(得分:0)
我已经通过将Vertex
类与Edge
类分离来为解决方案做出妥协,如下所示。
Edge.h:
#ifndef EDGE_H
#define EDGE_H
template <class T> class Edge
{
private:
T* _source;
T* _dest;
long long _weight;
...
};
#endif
在Vertex.h
中,向量变为std::vector<Edge<Vertex<T> > >
。如果需要,可以使用typedef Edge<Vertex<T> > Edge
和Vertex.h
中的公开Graph.h
简化这一过程。因此,消除了循环依赖性,并且可以单独使用每个类别&#34;明确地不包括另一个:现在Graph.h
取决于Vertex.h
,这取决于Edge.h
。
作为一个侧面说明来解决关于拥有其边缘的顶点的注释:我正在扩展我已经完成的图形类的实现,并且算法将是即插即用的(只需极少的更改)我保持相同/相似的邻接列表结构。