一切都很好,最后一个问题很烦人。编译很棒,但是链接失败:
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**
障碍物
#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
我有什么问题?我可以发布您需要分析的任何代码。
最佳答案
您声明了一个非抽象类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和typeinfo。
您的代码将破坏该方案:您将
Obstacle.hh
包含在某个编译单元中,编译器将具有Obstacle
的类collidesWith
视为第一个非内联虚拟成员函数,但当前编译单元中未定义该类,因此编译器认为可以推迟为该类创建vtable和typeinfo。由于没有collidesWith
的定义,因此在链接程序时它们都最终丢失。