C++ - 解决头文件中模板化类循环依赖关系的最佳约定?
C++ - Best convention to resolve templated classes' circular dependencies in header files?
我正在C++编写自己的模板化Graph
类的实现,所以我也在实现模板化Vertex
和Edge
类。 因此,实现必须位于各自的头文件中,而不是单独的.cpp
文件中。 (这里的首要答案对我不起作用(
我的 Vertex
类将外边的邻接列表存储为 Edge
s 的vector
,Edge
类存储指向源和目标 Vertex
s 的指针以及边的权重。
由于Edge
只存储指向Vertex
的指针,因此在Edge.h
中转发声明Vertex
类就足够了。 然后我可以#include "Edge.h"
Vertex.h
的顶部.
这是解决Vertex
类和Edge
类的共同依赖关系的最佳方法吗?用户必须#include
两个文件才能使用任何一个文件(即在Graph.h
中(。
如果用户想要使用Vertex
而不必显式包含Edge.h
反之亦然,该怎么办? 我应该转发声明并在另一个内部#include
吗?
还是应该在同一个头文件中实现它们?
如果有的话,STL如何解决这个问题?
这是我现在拥有的:
边缘:
#ifndef _EDGE_H__
#define _EDGE_H__
template <class T> class Vertex;
template <class T>
class Edge
{
private:
Vertex<T>* _source;
Vertex<T>* _dest;
unsigned long long _weight;
...
};
#endif
Vertex.h:
#ifndef _VERTEX_H__
#define _VERTEX_H__
#include "Edge.h"
#include <vector>
template <class T>
class Vertex
{
private:
std::vector<Edge<T> > _adj;
...
};
#endif
如果用户想要使用顶点而不必显式包含 Edge.h 或反之亦然,该怎么办?
由于您本质上是在谈论设计一个Graph
类,因此将两个标头都包含在其中并没有什么不好。然后,用户只会#include "graph.h"
(或任何你称之为文件的东西(,而不是真正关心它在较低级别上是如何设计的。
话虽如此 - 如果你想让你的类设计保持目前的方式 - 你的解决方案是一个好主意。但是,正如评论中已经提到的,顶点不需要拥有其边缘。也许你应该考虑一个不同的结构:
template<typename vertexType, typename edgeType>
class graph{
std::map<std::pair<vertexType,vertexType>, edgeType>;
};
请记住,使用此设计,特定方法的编写可能会更复杂(并且可能更慢(。但是 - 您最终会在此过程中使用更少的内存。根据你真正想要实现的目标(小尺寸或快速工作(,你最终可能会使用不同的图形结构。
一个解决方案的折衷方案,将Vertex
类与Edge
类分离,如下所示。
边缘:
#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> > >
.如果需要,可以通过Vertex.h
和Graph.h
的公共typedef Edge<Vertex<T> > Edge
来简化这一点。 因此,消除了循环依赖性,每个类都可以"单独"使用,而无需显式包含另一个类:现在Graph.h
取决于Vertex.h
取决于Edge.h
。
作为解决有关拥有其外边缘的顶点的评论的旁注:我正在扩展我编写的图形类的已经完整的实现,并且只有当我保持相同/相似的邻接列表结构时,算法才会即插即用(更改最少(。
- C++GTKMM gui循环依赖关系
- 如何在头文件中声明类模板(由于循环依赖关系)
- 对在不同二进制文件中创建的对象文件的依赖关系
- 使用Bazel构建具有不同编译器/链接器选项的C/C++依赖关系
- OpenVINO - 推理库插件 libMKLDNNPlugin.so 无法解析依赖关系
- 模拟测试中类的依赖关系
- C++模板方法中的循环依赖关系
- 解析正交模块的依赖关系
- 如何在 Mac OS 上安装 boost-mpi 及其对 clang 的依赖关系?
- Wt::D bo 中的循环依赖关系
- 在包含窗口标头时难以解决循环依赖关系问题
- 当依赖关系和依赖关系都是多态时,在哪个继承级别存储依赖关系指针?
- 解决循环依赖关系 c++ 的想法
- C++循环依赖关系,未声明的标识符
- C++ 中的循环依赖关系问题
- 为什么包含需要进一步的依赖关系?
- 使用 cmake 获取外部依赖关系
- CMake 外部和内部静态库的循环依赖关系
- 在没有Xcode的macOS中开发具有依赖关系的应用程序
- "std::shared_ptr"循环依赖关系是如何导致问题的