【问题标题】:undefined reference to `vtable for Player'未定义对“播放器的 vtable”的引用
【发布时间】:2022-01-13 00:52:40
【问题描述】:

我查看了很多其他类似的问题,但似乎都没有帮助。 我以前使用过虚函数,但这次它们似乎不起作用。

父类的标题:

#ifndef OBJECT_OBJECT
#define OBJECT_OBJECT
#include <raylib.h>
#include <raymath.h>

class Object {
public:
    Object() {}
    Object(Rectangle rect, Color color);
    Object(int x, int y, int width, int height, Color color);
    virtual void Update(float deltaTime) {}
    Rectangle rect;
    Color color;
};

#endif /* OBJECT_OBJECT */

父类的来源:

#include "Object.hpp"

Object::Object(Rectangle rect, Color color) {
    this->rect = rect;
    this->color = color;
}

Object::Object(int x, int y, int width, int height, Color color) {
    this->rect = { (float)x, (float)y, (float)width, (float)height };
    this->color = color;
}

子标题:

#ifndef OBJECT_OBJECTS_PLAYER
#define OBJECT_OBJECTS_PLAYER
#include <stdio.h>
#include "../Object.hpp"

class Player : public Object {
public:
    Player() {}
    Player(Rectangle rect, Color color) : Object(rect, color) {}
    Player(int x, int y, int width, int height, Color color) : Object(x, y, width, height, color) {}
    void Update(float deltaTime) override;
    int speed = 10;
};

#endif /* OBJECT_OBJECTS_PLAYER */

孩子的来源:

#include "Player.hpp"

void Player::Update(float deltaTime) {
    if (IsKeyPressed(KEY_W | KEY_UP)) this->rect.y -= speed * deltaTime;
    if (IsKeyPressed(KEY_S | KEY_DOWN)) this->rect.y += speed * deltaTime;
    if (IsKeyPressed(KEY_A | KEY_LEFT)) this->rect.x -= speed * deltaTime;
    if (IsKeyPressed(KEY_D | KEY_RIGHT)) this->rect.x += speed * deltaTime;
}

完整的 main.cpp 文件:

#include <raylib.h>
#include <raymath.h>
#include <vector>
#include <string>
#include "Object/Object.hpp"
#include "Object/Objects/Player.hpp"

void NewObject(Rectangle rect, Color color);
void NewObject(Object obj);
std::vector<Object> objects;
bool shouldClose;
int screenWidth;
int screenHeight;

int main(void) {
    InitWindow(0, 0, "2D Platformer");
    screenWidth = GetScreenWidth();
    screenHeight = GetScreenHeight();
    SetExitKey(-1);
    ToggleFullscreen();

    Player player({ 0, 0, 20, 20 }, (Color){0, 255, 0, 255});
    NewObject(player);

    Camera2D camera = { 0 };
    camera.target = (Vector2){0, 0};
    camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
    camera.rotation = 0.0f;
    camera.zoom = 1.0f;

    while (!WindowShouldClose()) {
        float deltaTime = GetFrameTime();
        BeginDrawing();

            ClearBackground(RAYWHITE);
            
            BeginMode2D(camera);

                for (int i = 0; i < objects.size(); i++) {
                    objects[i].Update(deltaTime);
                    DrawRectangleRec(objects[i].rect, objects[i].color);
                }

            EndMode2D();

        EndDrawing();
    }
    CloseWindow();

    return 0;
}

void NewObject(Rectangle rect, Color color) {
    objects.push_back(*(new Object(rect, color)));
}

void NewObject(Object obj) {
    objects.push_back(obj);
}

CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.11)
project(safcal)
cmake_policy(SET CMP0076 NEW)
find_package(raylib 3.0 QUIET)

if (NOT raylib_FOUND)
  include(FetchContent)

  FetchContent_Declare(
    raylib
    URL https://github.com/raysan5/raylib/archive/master.tar.gz
  )

  FetchContent_GetProperties(raylib)
  if (NOT raylib_POPULATED)
    set(FETCHCONTENT_QUIET NO)
    FetchContent_Populate(raylib)

    set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
    add_subdirectory(${raylib_SOURCE_DIR} ${raylib_BINARY_DIR})

  endif()

endif()
add_executable(${PROJECT_NAME})
target_sources(${PROJECT_NAME} PRIVATE main.cpp)
add_subdirectory(Object)
target_link_libraries(${PROJECT_NAME} raylib)

target_sources(${PROJECT_NAME} PRIVATE 
    "Object.cpp"
)

target_sources(safcal PRIVATE 
    "Player.cpp"
)

问题在于更新功能。评论与它被覆盖有关的任何内容都会停止错误。

编辑: 完整的错误

[build] FAILED: safcal 
[build] : && /bin/x86_64-linux-gnu-g++-10 -g  CMakeFiles/safcal.dir/main.cpp.o CMakeFiles/safcal.dir/Object/Object.cpp.o -o safcal  _deps/raylib-build/raylib/libraylib.a  -lm  -lpthread  /usr/lib/x86_64-linux-gnu/libGL.so  /usr/lib/x86_64-linux-gnu/libGLU.so  _deps/raylib-build/raylib/external/glfw/src/libglfw3.a  -lpthread  /usr/lib/x86_64-linux-gnu/librt.so  -lm  -ldl && :
[build] /usr/bin/ld: CMakeFiles/safcal.dir/main.cpp.o: warning: relocation against `_ZTV6Player' in read-only section `.text._ZN6PlayerC2E9Rectangle5Color[_ZN6PlayerC5E9Rectangle5Color]'
[build] /usr/bin/ld: CMakeFiles/safcal.dir/main.cpp.o: in function `Player::Player(Rectangle, Color)':
[build] /home/callum/Documents/Programming/C++/SafCal/build/../Object/Objects/Player.hpp:9: undefined reference to `vtable for Player'
[build] /usr/bin/ld: warning: creating DT_TEXTREL in a PIE

【问题讨论】:

  • 但似乎最普通和最常见的问题是您没有将“儿童源”链接到您的程序。
  • 我使用 target_sources 在 cmakelists.txt 中添加了它。这够好吗?
  • 你应该粘贴具体的错误信息。
  • virtual 析构函数放入Object,看看是否会发生奇迹。
  • @user4581301 添加似乎导致更多问题 [build] /usr/bin/ld: CMakeFiles/safcal.dir/main.cpp.o: in function Player::Player(Rectangle, Color)': [build] /home/callum/Documents/Programming/C++/SafCal/build/../Object/Objects/Player.hpp:9: undefined reference to vtable for Player' [ build] /usr/bin/ld: CMakeFiles/safcal.dir/main.cpp.o: in function Player::~Player()': [build] /home/callum/Documents/Programming/C++/SafCal/build/../Object/Objects/Player.hpp:6: undefined reference to vtable for Player'

标签: c++ g++


【解决方案1】:

我以前使用过虚函数,但这次它们似乎不起作用。

Object slicing出现在你的代码中,所以你看不到想要的结果。

Player player({ 0, 0, 20, 20 }, (Color){0, 255, 0, 255});
NewObject(player);

您可以尝试进行以下更改:

std::vector<std::shared_ptr<Object>> objects;

...

void NewObject(std::shared_ptr<Object> obj) {
    objects.push_back(obj);
}

...

NewObject(new Player());

另外,基类的析构函数需要声明为虚函数。

【讨论】:

    猜你喜欢
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多