【发布时间】:2011-06-25 23:55:07
【问题描述】:
我正在用 C++ 做一个小项目,但遇到了一些关于虚函数的问题。
我有一个带有一些虚函数的基类:
#ifndef COLLISIONSHAPE_H_
#define COLLISIONSHAPE_H_
namespace domino
{
class CollisionShape : public DominoItem
{
public:
// CONSTRUCTOR
//-------------------------------------------------
// SETTERS
//-------------------------------------------------
// GETTERS
//-------------------------------------------------
virtual void GetRadius() = 0;
virtual void GetPosition() = 0;
virtual void GetGrowth(CollisionShape* other) = 0;
virtual void GetSceneNode();
// OTHER
//-------------------------------------------------
virtual bool overlaps(CollisionShape* shape) = 0;
};
}
#endif /* COLLISIONSHAPE_H_ */
还有一个 SphereShape 类,它扩展了 CollisionShape 并实现了上述方法
/* SphereShape.h */
#ifndef SPHERESHAPE_H_
#define SPHERESHAPE_H_
#include "CollisionShape.h"
namespace domino
{
class SphereShape : public CollisionShape
{
public:
// CONSTRUCTOR
//-------------------------------------------------
SphereShape();
SphereShape(CollisionShape* shape1, CollisionShape* shape2);
// DESTRUCTOR
//-------------------------------------------------
~SphereShape();
// SETTERS
//-------------------------------------------------
void SetPosition();
void SetRadius();
// GETTERS
//-------------------------------------------------
void GetRadius();
void GetPosition();
void GetSceneNode();
void GetGrowth(CollisionShape* other);
// OTHER
//-------------------------------------------------
bool overlaps(CollisionShape* shape);
};
}
#endif /* SPHERESHAPE_H_ */
和 .cpp 文件:
/*SphereShape.cpp*/
#include "SphereShape.h"
#define max(a,b) (a>b?a:b)
namespace domino
{
// CONSTRUCTOR
//-------------------------------------------------
SphereShape::SphereShape(CollisionShape* shape1, CollisionShape* shape2)
{
}
// DESTRUCTOR
//-------------------------------------------------
SphereShape::~SphereShape()
{
}
// SETTERS
//-------------------------------------------------
void SphereShape::SetPosition()
{
}
void SphereShape::SetRadius()
{
}
// GETTERS
//-------------------------------------------------
void SphereShape::GetRadius()
{
}
void SphereShape::GetPosition()
{
}
void SphereShape::GetSceneNode()
{
}
void SphereShape::GetGrowth(CollisionShape* other)
{
}
// OTHER
//-------------------------------------------------
bool SphereShape::overlaps(CollisionShape* shape)
{
return true;
}
}
这些类以及其他一些类被编译到一个共享库中。
Building libdomino.so
g++ -m32 -lpthread -ldl -L/usr/X11R6/lib -lglut -lGLU -lGL -shared -lSDKUtil -lglut -lGLEW -lOpenCL -L/home/adrian/AMD-APP-SDK-v2.4-lnx32/lib/x86 -L/home/adrian/AMD-APP-SDK-v2.4-lnx32/TempSDKUtil/lib/x86 -L"/home/adrian/AMD-APP-SDK-v2.4-lnx32/lib/x86" -lSDKUtil -lglut -lGLEW -lOpenCL -o build/debug/x86/libdomino.so build/debug/x86//Material.o build/debug/x86//Body.o build/debug/x86//SphereShape.o build/debug/x86//World.o build/debug/x86//Engine.o build/debug/x86//BVHNode.o
当我编译使用此库的代码时,我收到以下错误:
../../../lib/x86//libdomino.so: undefined reference to `vtable for domino::CollisionShape'
../../../lib/x86//libdomino.so: undefined reference to `typeinfo for domino::CollisionShape'
用于编译使用该库的演示的命令:
g++ -o build/debug/x86/startdemo build/debug/x86//CMesh.o build/debug/x86//CSceneNode.o build/debug/x86//OFF.o build/debug/x86//Light.o build/debug/x86//main.o build/debug/x86//Camera.o -m32 -lpthread -ldl -L/usr/X11R6/lib -lglut -lGLU -lGL -lSDKUtil -lglut -lGLEW -ldomino -lSDKUtil -lOpenCL -L/home/adrian/AMD-APP-SDK-v2.4-lnx32/lib/x86 -L/home/adrian/AMD-APP-SDK-v2.4-lnx32/TempSDKUtil/lib/x86 -L../../../lib/x86/ -L"/home/adrian/AMD-APP-SDK-v2.4-lnx32/lib/x86"
(-ldomino 标志)
当我运行演示时,我手动告诉它有关库的信息:
LD_LIBRARY_PATH=../../lib/x86/:$AMDAPPSDKROOT/lib/x86:$LD_LIBRARY_PATH bin/x86/startdemo
在阅读了一些关于虚函数和虚表的内容后,我了解到虚表是由编译器处理的,我不应该担心它,所以我对如何处理这个问题有点困惑。
我正在使用gcc version 4.6.0 20110530 (Red Hat 4.6.0-9) (GCC)
后期编辑: 真的很抱歉,我这里是直接手写代码的。 我已经在代码中定义了返回类型。 我向下面回答的 2 人道歉。
我不得不提一下,我是在 C++ 中使用更复杂项目布局的初学者。我的意思是更复杂的 makefile、共享库之类的东西。
我的问题是因为我没有定义 virtual void CollisionShape::GetSceneNode() 的主体。
解决这个问题的方法是定义上述函数,或者将其声明为纯虚函数:
virtual void CollisionShape::GetSceneNode() = 0;
【问题讨论】:
-
@adivasile:请发布一个最小的 sn-p 编译并显示问题。当你去解决没有返回类型的问题时,你颠倒了函数返回的类型。当存在与实际情况无关的红鲱鱼时,有时很难诊断错误。还请提供使用该库的代码的命令行,因为这是您看到错误的地方。
-
@Michael Burr:我添加了用于链接库的代码。至于 sn-p,我不确定我是否可以提供,因为涉及很多文件和依赖项。
-
正如发布的那样,您的代码正在自找麻烦。
CollisionShape需要一个虚拟析构函数。也许您声明了它,但忘记定义了?很难说有一个不可编译的 sn-p。 -
接近可编译了。将返回类型替换为
void,删除不相关的包含和函数体,就是这样。 -
好的,我添加了两个类的完整定义,并删除了返回类型和包含。如果我遗漏了什么,请告诉我。
标签: c++ virtual-functions vtable typeinfo