我有一个名为Edge的类和一个名为Vertex的类
在我的Edge类中,有一个名为target的Vertex的引用。在Vertex中我发送一个Edge并尝试通过Edge更改目标,但是我遇到类Edge的编译错误没有名为target的成员。
我的Edge.h是
#include "Vertex.h"
class Edge
{
public:
Edge *data;
Edge *next;
Vertex *target;
Edge();
Edge(Edge *x);
Edge(Vertex *x);
void print();
};
错误是由Vertex.cpp中的此代码引起的。
Vertex::Vertex(Edge *x)
{
name = x->target->name;
next = x->target->next;
mark = x->target->mark;
previous = NULL;
next = NULL;
}
我尝试编译Vertex时的确切错误是
g++ -g -I. -c -o Vertex.o Vertex.cpp
In file included from Vertex.h:3,
from Vertex.cpp:3:
Edge.h:10: error: ISO C++ forbids declaration of ‘Vertex’ with no type
Edge.h:10: error: expected ‘;’ before ‘*’ token
Edge.h:14: error: expected ‘)’ before ‘*’ token
Vertex.cpp: In constructor ‘Vertex::Vertex(Edge*)’:
Vertex.cpp:26: error: ‘class Edge’ has no member named ‘target’
Vertex.cpp:27: error: ‘class Edge’ has no member named ‘target’
Vertex.cpp:28: error: ‘class Edge’ has no member named ‘target’
答案 0 :(得分:1)
如果我理解正确的情况,似乎你在.cpp中有Edge的类声明,而不是.h(标题中有什么?)。 Vertex中出现错误是因为当编译器查找Edge类时,它无法在Edge标头中找到声明 - 换句话说,它是隐藏的。 Edge类声明应该在头文件中,定义应该在.cpp中。另请注意,这是循环依赖的一个很好的例子,这通常会导致痛苦。看看你是否能打破它们。
编辑:感谢你把确切的错误放在那里,它几乎证实了我们所有的猜测。确保两个类可以相互看到 - 确保Vertex包含Edge的标题。如果类足够小,你可能想把它们都放在一个文件中,就像Falmarri建议的那样。另外,不要忘记使用forward declarations来解决这些类型的循环依赖关系。如果在类中包含指向外部类的指针或引用,则可以转发声明,但它不适用于类中的实际对象(如Edge edge;
)。我相信这样做的原因是指针和引用只是地址,所以编译器不需要知道内部结构,但是要使用实际的对象,你必须知道内部是什么。
答案 1 :(得分:1)
所有其他答案都正确地解释了您对两个类之间的循环依赖性存在问题,并解释了如何解决它。
我的建议是让Vertex类不知道Edge类。只需将getTargetVertex()和getSourceVertex()方法添加到边类,并仅使用Vertex类中的复制构造函数。
当然,这个解决方案将很难知道在没有检查可用池/边缘列表中的每个边缘实例的情况下,目标顶点的边缘是什么。
答案 2 :(得分:0)
在Edge.h中放置边缘声明,并在Vertex.cpp中包含Edge.h。
答案 3 :(得分:0)
似乎你有一个循环依赖。您可以通过在class
声明中的class Vertex *target;
未声明的类名称之前添加Edge
来解决此问题。