奇怪的未定义的Vtable错误引用

时间:2012-02-17 05:26:59

标签: c++ polymorphism abstract-class vtable undefined-reference

......无论出于什么原因,我似乎无法弄明白。我也试过在Qt中清理我的构建文件,这似乎也没有用。

首先,让我说明我很清楚,当C ++类继承具有纯虚函数的抽象类时,这个错误通常会出现,并且继承类(无论出于何种原因)还没有定义它们。

问题是没有纯虚函数与指定的错误相关

我有一个称为CoordinateObject的基类,它带有一个抽象类Shape,它继承自该基类,还有一个FirstPersonCamera类,它继承自{{1} }}。现在,我的CoordinateObject类继承自Cubef,当我尝试编译代码时,出现以下错误:

Shape

最初当./debug\Camera.o:Camera.cpp:(.rdata$_ZTVN6Engine17FirstPersonCameraE[vtable for Engine::FirstPersonCamera]+0x10): undefined reference to `Engine::FirstPersonCamera::InitCoordinates()' ./debug\Cubef.o:Cubef.cpp:(.rdata$_ZTVN6Engine5CubefE[vtable for Engine::Cubef]+0x1c): undefined reference to `Engine::Cubef::InitCoordinates()' 具有纯虚函数CoordinateObject时会出现这种情况,但是,在尝试在每个选择继承它的类中正确实现之后,它仍然无法正常工作。因此,我删除了它(除了基类本身之外的每个类实现和声明)。

所以,我需要确切地知道我在做什么错误。我将发布如下代码:

代码

CoordinateObject.h

InitCoordinates

Shape.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 );
    };

Cubef.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 );
    };
}

最后, Camera.h

#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:

    };

}

我甚至尝试在任何派生类的初始化列表中初始化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; }; } 的ctor的默认构造函数,但老实说,我怀疑这会有所不同。

示例

(来自 Shape.h

CoordinateObject

如您所见,Shape::Shape( Vector3f& center, float radius ) : CoordinateObject(), mRadius( radius ) { InitShape( center ); } 的构造函数在此处调用,初始化列表中,即使它是默认的。

我不知道该怎么做。

HALP?

2 个答案:

答案 0 :(得分:3)

从错误消息中,它看起来肯定你有过时的debug \ Camera.o和debug \ Cubef.o文件(当InitCoordinates()为虚拟时遗留下来。)

不要相信你的make clean - 查看那些.o文件的时间戳或手动删除它们。

通常,当构建在Debug中工作并在Release中失败时,原因是:

  • 陈旧文件(makefile问题 - 具体而言,makedepend不准确)
  • #ifdef是在一个构建中触发而不是在另一个构建中触发的(硬编码或来自-D标志)

根据我的经验,我遇到了两种类型的错误。

答案 1 :(得分:0)

<强>更新

我在MinGW的Debug下进行了编译,但是现在我切换到Release(无论出于何种原因),它有效!

为什么这样工作,我不太确定。也许是Qt(或MinGW,甚至)的某种故障?