我对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);
};
上面的代码给出了以下错误:
如何解决此问题?
答案 0 :(得分:6)
您需要的是在Edge
中使用Vertex
之前向前声明class Edge;
class Vertex {
string name;
int distance;
...
};
class Edge { ... };
类:
Vertex
您不能放置Vertex
类型的成员而不是Vertex
本身的声明,因为C ++不允许递归类型。在C ++的语义中,这种类型的大小需要是无限的。
当然,您可以在Vertex
中指出Vertex
。
事实上,在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);
};
的边缘和邻接列表中,您想要的是指针,而不是对象的副本。因此,您的代码应该像下面那样修复(假设您使用的是C ++ 11,实际上您现在应该使用它):
{{1}}
答案 1 :(得分:2)
如果你考虑一下,实例化一个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建议你应该阅读forward declarations,你可能还需要学习更多关于指针和参考的知识。
由于您仍然遇到问题,我会更详细地更新我的答案。我读到您实际上已经将类拆分为两个头文件,我认为它们是Vertex.h
和Edge.h
。他们应该看起来像这样
<强> Vertex.h 强>
class Edge;
class Vertex
{
Edge* CreateEdge(); // Declaration of a class function
// ...
};
<强> Edge.h 强>
class Vertex
class Edge
{
// ...
};
当您想要使用它来访问其成员或创建实例时,您需要包含Edge
的完整定义。基本上,您需要在定义所有类和结构之后放置每个函数的实现。最简单的方法是将函数实现放在各自的.cpp
文件中。您似乎想在Edge
课程中创建Vertex
对象,因此您需要在Vertex
的{{1}}文件中执行此操作。
<强> Vertex.cpp 强>
.cpp
因为在此#include "Vertex.h"
#include "Edge.h"
Edge* Vertex::CreateEdge()
{
return new Edge();
}
文件中完成的第一件事是包含.cpp
和Vertex
头文件,它们具有各自的类定义,所以您可以完全使用Edge
和Vertex
课程。
您需要在如何组织声明和定义方面有一定的顺序,如下所示
Edge