一切都很好,最后的问题很烦人。编译很好,但链接失败:
bash-3.2$ make
g++ -Wall -c -g Myworld.cc
g++ -Wall -g solvePlanningProblem.o Position.o AStarNode.o PRM.o PRMNode.o World.o SingleCircleWorld.o Myworld.o RECTANGLE.o CIRCLE.o -o solvePlanningProblem
**Undefined symbols:
"vtable for Obstacle", referenced from:
Obstacle::Obstacle()in Myworld.o
"typeinfo for Obstacle", referenced from:
typeinfo for RECTANGLEin RECTANGLE.o
typeinfo for CIRCLEin CIRCLE.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [solvePlanningProblem] Error 1**Obstacle.hh
#ifndef Obstacle_hh
#define Obstacle_hh
#include <vector>
#include <iostream>
class Obstacle{
public:
Obstacle(){}
virtual bool collidesWith(double x,double y);
virtual void writeMatlabDisplayCode(std::ostream &fs);
virtual ~Obstacle(){}
};
#endif
我有什么问题?我可以发布任何你需要的代码来分析它。
发布于 2009-11-08 08:21:15
您声明了一个非抽象类Obstacle,但并没有实现它的所有成员函数。
最好将其声明为抽象类:
class Obstacle{
public:
Obstacle(){} // this is superfluous, you can (and should) remove it
virtual bool collidesWith(double x,double y) = 0;
virtual void writeMatlabDisplayCode(std::ostream &fs) = 0;
virtual ~Obstacle(){}
};原因是您可以在许多C++编译器中找到一个启发式方法--在定义类的第一个非内联虚拟成员函数(如果它有一个)时,为了避免不必要地为类创建重复的vtable和typeinfos。
您的代码破坏了这种方案:您将Obstacle.hh包含到某个编译单元中,编译器看到一个类Obstacle将collidesWith作为第一个非内联虚拟成员函数,但它没有在当前编译单元中定义,因此编译器认为它可以推迟为该类创建vtable和typeinfo。因为没有collidesWith的定义,所以当程序被链接时,它们都会丢失。
发布于 2009-11-08 07:26:56
显然,您缺少对象文件或库。定义和声明障碍物的对象。
可以在Myworld中引用的头文件(*.h)中查找它,因为这将使您了解Myworld使用的对象背后的cpp/库(通常具有相同的名称)。
编辑,给出Lisa的回复:
不需要,您不需要在源代码中添加任何*.hh文件。问题出在链接时,而不是编译时。
某处不是有一个Obstacle.cpp文件吗?这将需要进行编译,并且需要将相应的.o文件添加到make中的最后一行gcc。
对啰!在看到Obstacle.hh时
这两个虚方法并不是纯虚的,因此编译器希望以某种方式在某个地方定义它们。而且构造函数和析构函数也没有定义。
最简单的方法可能是编写类似这样的代码:
class Obstacle{
public:
// Obstacle();
virtual bool collidesWith(double x,double y) = 0; // = 0 makes them pure virtual
virtual void writeMatlabDisplayCode(std::ostream &fs) = 0;
//~Obstacle();
};或者,您可以声明一个小的不做任何事情的构造函数和析构函数,或者您可以使析构函数成为纯虚的,以强制派生类实现析构函数……
发布于 2009-11-08 08:06:22
类障碍需要一个虚拟析构函数。将析构函数定义更改为:
virtual ~Obstacle();析构函数的定义还为具有虚函数的类创建了vtable。它还确保通过基类指针删除派生类实例的操作是正确的。
https://stackoverflow.com/questions/1694785
复制相似问题