C++类中的循环依赖关系
Circular dependency in C++ classes
我对C++相对较新,并且面临循环依赖问题。有人可以帮我解决这个问题吗?
我有两个类:
class Vertex {
string name;
int distance;
//Vertex path;
int weight;
bool known;
list<Edge> edgeList;
list<Vertex> adjVertexList;
public:
Vertex();
Vertex(string nm);
virtual ~Vertex();
};
class Edge {
Vertex target;
int weight;
public:
Edge();
Edge(Vertex v, int w);
virtual ~Edge();
Vertex getTarget();
void setTarget(Vertex target);
int getWeight();
void setWeight(int weight);
};
上面的代码给出了以下错误:
- "顶点"不命名类型
- "顶点"尚未声明
- 在"v"之前应为")"
如何解决此问题?
您所需要的只是在Edge
类在Vertex
中使用之前转发声明它:
class Edge;
class Vertex {
string name;
int distance;
...
};
class Edge { ... };
不能放置类型 Vertex
的成员而不是Vertex
本身的声明,因为C++不允许递归类型。在C++的语义中,这种类型的大小需要是无限的。
当然,您可以在Vertex
内放置指向Vertex
的指针。
事实上,在Vertex
的边缘和邻接列表中,你想要的是指针,而不是对象的副本。因此,您的代码应该像下面这样修复(假设您使用C++11,实际上您现在应该使用它):
class Edge;
class Vertex {
string name;
int distance;
int weight;
bool known;
list<shared_ptr<Edge>> edgeList;
list<shared_ptr<Vertex>> adjVertexList;
public:
Vertex();
Vertex(const string & nm);
virtual ~Vertex();
};
class Edge {
Vertex target;
int weight;
public:
Edge();
Edge(const Vertex & v, int w);
virtual ~Edge();
Vertex getTarget();
void setTarget(const Vertex & target);
int getWeight();
void setWeight(int weight);
};
如果您考虑一下,实例化单个Vertex
或Edge
对象将实例化无限数量的更多Vertex
和Edge
对象,因为它们中的每一个都包含彼此的实例。
要解决此问题,您需要转发声明一个类,哪个类取决于您首先使用的类。前向声明类允许您使用指针和对它们的引用,而无需实际使用该类,而仅指向它。
此代码段应该是可编译的,但它需要一些额外的内存管理。
class Edge; // This is a forward declaration
class Vertex {
string name;
int distance;
//Vertex path;
int weight;
bool known;
list<Edge*> edgeList;
list<Vertex*> adjVertexList;
public:
Vertex();
Vertex(string nm);
virtual ~Vertex();
};
class Edge {
Vertex* target;
int weight;
public:
Edge();
Edge(Vertex* v, int w);
virtual ~Edge();
Vertex* getTarget();
void setTarget(Vertex* target);
int getWeight();
void setWeight(int weight);
};
这段代码之所以可以编译,是因为类现在包含指向对象的指针,而不是对象本身。
正如BartoszKP建议的那样,您应该阅读前向声明,并且可能还需要了解有关指针和引用的更多信息。
由于您仍然遇到麻烦,我将用更多详细信息更新我的答案。我读到您现在实际上已将类拆分为两个头文件,我假设它们是Vertex.h
和Edge.h
.它们应该看起来像这样
顶点
class Edge;
class Vertex
{
Edge* CreateEdge(); // Declaration of a class function
// ...
};
边缘.h
class Vertex
class Edge
{
// ...
};
当您想要使用它来访问其成员或创建实例时,您需要包含Edge
的完整定义。基本上,您需要将每个函数的实现放在定义所有类和结构之后。最简单的方法是将函数实现放在各自的.cpp
文件中。似乎您想从Vertex
类中创建一个Edge
对象,因此您需要在Vertex
的.cpp
文件中执行此操作。
顶点.cpp
#include "Vertex.h"
#include "Edge.h"
Edge* Vertex::CreateEdge()
{
return new Edge();
}
由于在此.cpp
文件中要做的第一件事是包括具有各自类定义的Vertex
和Edge
头文件,因此您可以根据需要完全使用 Vertex
和Edge
类。
在如何组织声明和定义时,您将需要一定的顺序,如下所示
// Regarding global functions
Declaration // void MyFunction();
Definition // void MyFunction() { ... }
// Regarding classes and structs
Declaration // class MyClass; - Forward declaration in another header file
Definition // class MyClass { ... } - Definition in actual header file
// Regarding class functions
Declaration // class MyClass { void MyFunction(); }
Definition // void MyClass::MyFunction() { ... }
- 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"循环依赖关系是如何导致问题的