C++ 对Vtable错误的奇怪的未定义引用

C++ 对Vtable错误的奇怪的未定义引用,c++,polymorphism,abstract-class,vtable,undefined-reference,C++,Polymorphism,Abstract Class,Vtable,Undefined Reference,…不管出于什么原因,我似乎无法理解。我也尝试过在Qt中清理构建文件,但这似乎也不起作用 首先,让我声明,当C++类继承了纯函数的抽象类,继承类(无论什么原因)还没有定义时,这个错误通常会发生。p> 问题是没有与指定错误相关的纯虚拟函数 我有一个名为CoordinateObject的基类,它有一个抽象类Shape,它继承自该基类,还有一个FirstPersonCamera类,它也继承自CoordinateObject。现在,我的Cubef类继承自Shape,当我尝试编译代码时,出现以下错误: ./

…不管出于什么原因,我似乎无法理解。我也尝试过在Qt中清理构建文件,但这似乎也不起作用

首先,让我声明,当C++类继承了纯函数的抽象类,继承类(无论什么原因)还没有定义时,这个错误通常会发生。p> 问题是没有与指定错误相关的纯虚拟函数

我有一个名为
CoordinateObject
的基类,它有一个抽象类
Shape
,它继承自该基类,还有一个
FirstPersonCamera
类,它也继承自
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()'
最初,当
coordinationobject
确实有一个纯虚拟函数
initcoordinations
时出现了这种情况,但是,在尝试在选择从它继承的每个类中正确实现它之后,它仍然不起作用。因此,我删除了它(以及除基类本身之外的每个类实现和声明)

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

代码

协调对象

形状.h

立方英尺

最后是照相机

我甚至尝试过在任何派生类的初始化列表中初始化
CoordinateObject
的构造函数的默认构造函数,但老实说,我怀疑这会有什么不同

示例

(摘自Shape.h)

如您所见,
CoordinateObject
的构造函数在这里被调用,在初始化列表中,即使它是默认的

我不知道该怎么办


Halp?

更新

我让它在MinGW的Debug下编译,但现在我切换到Release(出于任何原因),它工作了


为什么会这样,我不太清楚。可能是Qt(甚至是MinGW)出现了故障?

从错误消息来看,您显然有过时的debug\Camera.o和debug\Cubef.o文件(InitCoordinates()是虚拟的时候遗留下来的)

不要相信你的“清理”-查看这些.o文件上的时间戳或手动删除它们

通常,当构建在调试中工作,在发布中失败时,其原因是:

  • 陈旧文件(makefile问题——特别是MakeDependent不准确)
  • #在一个构建中触发但在另一个构建中未触发的ifdef(硬编码或from-D标志)

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

你有声明吗?你有定义吗?是的,我有。在调试模式下,尝试进行清理,然后重新生成。你可能有一个肮脏的身材。我会非常小心以一种模式编译的代码,而不是另一种模式编译的代码,但我不知道具体原因(在这种情况下,Qt或MinGW中出现小故障的可能性不大)。奇怪的是,我以前多次尝试清理,但仍然会得到相同的结果。从错误消息中,看起来您肯定有陈旧的debug\Camera.o和debug\Cubef.o文件(InitCoordinates()是虚拟的时候遗留下来的)。不要相信你的清理-查看那些.o文件上的时间戳或手动删除它们。不管是这样还是以某种方式,您仍然在包含路径中包含旧的CoordinateObject.h(您是否100%确定新的CoordinateObject.h已保存到磁盘?)@kfmfe04,您应该将您的回答转换为答案。它修复了我的问题,手动删除对象文件,正如你所建议的。我的存储库中的makefile已过期,因此未清除它们。
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 );
    };
#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:

    };

}
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;
    };

}
Shape::Shape( Vector3f& center, float radius )
    : CoordinateObject(),
      mRadius( radius )
{
    InitShape( center );
}