c++ - 对 Vtable 错误的奇怪 undefined reference

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

...无论出于何种原因,我似乎无法弄清楚。我也尝试过在 Qt 中清理我的构建文件,但似乎也没有用。

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

问题是不存在与指定错误相关的纯虚函数

我有一个称为 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()'

这最初是在 CoordinateObject did 有一个纯虚函数 InitCoordinates 时出现的,但是,在尝试在每个类中正确实现它之后选择继承,还是不行。因此,我删除了它(连同除基类本身之外的每个类实现和声明)。

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

代码

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

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

Cubef.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:

    };

}

最后,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 构造函数的默认构造函数,但老实说,我怀疑这有什么不同。

示例

(来自 Shape.h)

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

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

我不知道该怎么做。

暂停?

最佳答案

从错误消息来看,您肯定有陈旧的 debug\Camera.o 和 debug\Cubef.o 文件(InitCoordinates() 为虚拟时遗留的)。

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

通常,当构建在 Debug 中工作而在 Release 中失败时,这是由于:

  • 过时的文件(makefile 问题 - 特别是 makedepend 不准确)
  • #ifdef 在一个构建中被触发但在另一个构建中不被触发(硬编码或来自 -D 标志)

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

关于c++ - 对 Vtable 错误的奇怪 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9323342/

相关文章:

c++ - 库中命名空间的使用

c++ - 如何在声明时初始化成员对象?

c++ - DXGI_FORMAT_ 代码如何与字节顺序相关?

PHP OOP : interface vs. 非接口(interface)方法 - 示例

c++ - 使用 c malloc 函数分配内存的意外结果

ruby-on-rails - Ruby On Rails 功能测试 :index with a polymorphic model

c++ - boost::shared_ptr <> "explicit shared_ptr( Y * p ): px( p ), pn()//Y must be complete"

c# - 在抽象父类(super class)的子类中强制使用属性

java - 在 Java 中为对象赋值

抽象类中的 PHP 静态变量