对Vtable错误的奇怪的未定义引用
Strange Undefined Reference to Vtable Error
。。。不管出于什么原因,我似乎都搞不清楚。我也尝试过在Qt中清理我的构建文件,但似乎也不起作用。
首先,让我声明,我很清楚,当C++类继承了一个具有纯虚拟函数的抽象类,而继承类(无论出于何种原因)还没有定义它们时,通常会出现这个错误。
问题是不存在与指定的错误相关的纯虚拟函数。
我有一个称为CoordinateObject
的基类,其中有一个抽象类Shape
,它继承自该基类,还有一个FirstPersonCamera
类,它也继承自CoordinateObject
。现在,我的Cubef
类继承自Shape
,当我尝试编译代码时,我会得到以下错误:
./debugCamera.o:Camera.cpp:(.rdata$_ZTVN6Engine17FirstPersonCameraE[vtable for Engine::FirstPersonCamera]+0x10): undefined reference to `Engine::FirstPersonCamera::InitCoordinates()'
./debugCubef.o:Cubef.cpp:(.rdata$_ZTVN6Engine5CubefE[vtable for Engine::Cubef]+0x1c): undefined reference to `Engine::Cubef::InitCoordinates()'
最初,当CoordinateObject
确实有一个纯虚拟函数InitCoordinates
时,就会出现这种情况,然而,在尝试在每个选择继承它的类中正确实现它之后,它仍然不起作用。因此,我删除了它(以及除基类本身之外的所有类实现和声明)。
所以,我需要确切地知道我做错了什么。我会发布如下代码:
代码
坐标对象.h
class CoordinateObject
{
public:
CoordinateObject( void );
virtual ~CoordinateObject( void )
{
delete mWorld;
delete mObject;
delete mInertial;
}
Matrix3fv GetInertialSpace( void );
Matrix3fv GetObjectSpace( void );
Matrix3fv GetWorldSpace( void );
void SetInertialSpace( Matrix3fv* space );
void SetInertialSpace( Matrix3fv& space );
void SetObjectSpace( Matrix3fv* space );
void SetObjectSpace( Matrix3fv& space );
void SetWorldSpace( Matrix3fv* space );
void SetWorldSpace( Matrix3fv& space );
protected:
Matrix3fv* mWorld;
Matrix3fv* mObject;
Matrix3fv* mInertial;
private:
void InitCoordinates( void );
};
形状.h
#pragma once
#include "stdafx.h"
namespace Engine
{
class Circlef;
class Shape
: public CoordinateObject
{
public:
Shape( Vector3f& center, float radius );
virtual ~Shape( void )
{
delete mCenter;
}
virtual void Collide( Shape& s ) = 0;
virtual void Collide( const Circlef& s ) = 0;
Vector3f* Center( void );
virtual void Draw( void ) = 0;
void SetCenter( Vector3f newCenter );
void SetCenter( Vector3f* newCenter );
float mRadius;
protected:
Vector3f* mCenter;
private:
void InitShape( Vector3f& center );
};
}
立方英尺高度
#pragma once
#include "stdafx.h"
namespace Engine
{
class Cubef
: public Shape
{
public:
Cubef( Vector3f center, float radius );
virtual ~Cubef( void )
{
delete mCenter;
}
virtual void Collide( Shape& s );
virtual void Collide( const Circlef& s );
virtual void Draw( void );
void Draw( const Vector3f& camPosition );
void Draw( const Vector3f& newCenter, float radius, const Vector3f& camPosition );
void DrawFront( void );
void DrawBack( void );
void DrawLeft( void );
void DrawRight( void );
void DrawTop( void );
void DrawBottom( void );
inline double GetEdgeLength( void ) const
{
return mEdgeLength;
}
inline int GetCubeId( void ) const
{
return mCubeId;
}
inline double GetSurfaceArea( void ) const
{
return mSurfaceArea;
}
void Rotatef( float angle, AngleOfRotation aor );
void Rotatef( float angle, Vector3f* toRotate, AngleOfRotation aor );
protected:
static int CubeCount;
const int mCubeId;
float mSurfaceArea;
float mEdgeLength;
private:
};
}
最后,Camera.h
namespace Engine
{
extern const float PI;
extern const double MOUSE_Y_SENSITIVITY;
extern const double MOUSE_X_SENSITIVITY;
extern const int FP_CAM_QUAT_ARR_LEN;
class FirstPersonCamera
: public CoordinateObject
{
public:
FirstPersonCamera( void );
~FirstPersonCamera( void );
void Rotate( SDL_Event*& event );
inline Vector3f GetPosition( void ) const
{
return *mPosition;
}
inline Matrix3fv GetRotation( void ) const
{
return *mRotation;
}
void MoveCamera( const SDL_KeyboardEvent& event );
void UpdateCamera( void );
void UpdateCamera( const Vector3f& coords );
private:
void InitCamera( void );
Matrix3fv* mRotation;
Vector3f* mPosition;
float mAngle;
};
}
我甚至尝试过在任何派生类的初始化列表中初始化CoordinateObject
的ctor的默认构造函数,但老实说,我怀疑这有什么不同。
示例
(来自Shape.h)
Shape::Shape( Vector3f& center, float radius )
: CoordinateObject(),
mRadius( radius )
{
InitShape( center );
}
正如您所看到的,CoordinateObject
的构造函数在这里被调用,在初始化列表中,尽管它是默认的。
我不知道该怎么办。
暂停?
从错误消息来看,您肯定有过时的debug\Camer.o和debug\Cubef.o文件(InitCoordinates()是虚拟的时遗留下来的)。
不要相信你的make clean-查看那些.o文件上的时间戳或手动删除它们。
通常,当构建在Debug中工作而在Release中失败时,原因是:
- 陈旧文件(makefile问题,特别是makedependent不准确)
- #在一个构建中被触发但在另一个中没有被触发的ifdef(硬编码或来自-D标志)
根据我的经验,我遇到过这两种类型的错误。
更新
我在MinGW的Debug下编译了它,但现在我切换到Release(无论出于什么原因),它成功了!
为什么会这样,我不太确定。也许是Qt(甚至MinGW)出现了故障?
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 对 Scalar ::Scalar() 的未定义引用
- 对复制 CTOR 和 CTOR 的未定义引用
- 对显式实例化的模板函数的未定义引用
- TensorRT (C++ API) 对"createNvOnnxParser_INTERNAL"的未定义引用
- 2个模板化类的非模板友元函数未定义引用错误
- 编译 libfluid 样本控制器时对"event_base_del_virtual"的未定义引用
- 获取对function_name的未定义引用
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 对结构方法的未定义引用
- 使用内联函数 c++ 的未定义引用
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 对 DLOPEN 的未定义引用
- QT C++中对全局变量的未定义引用
- 快速数学导致对"__pow_finite"的未定义引用
- 对 boost::system::d etail::system_category_instance 的未定义引用,从
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用