Error: one or more multiply defined symbols found

Error: one or more multiply defined symbols found

我正在设置我的第一个正确的 SDL 项目和 C++ 项目,但出现错误。最后一个错误显示 one or more multiply defined symbols found。除了那个错误,我还收到了一堆错误,其中一个是:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2005 "public: bool __thiscall Game::init(void)" (?init@Game@@QAE_NXZ) already defined in 
game.obj    learnSDL    C:\Users\myself\source\repos\learn\learn\main.obj

我遇到的所有其他错误也采用相同的格式,但它们针对游戏中的不同属性 class。

game.h:

#pragma once

#include <iostream>
#include "SDL.h"

class Game
{
public:

    bool init();
    bool constructWindow
    (
        const char* windowName,
        uint16_t xWindowPos,
        uint16_t yWindowPos,
        uint16_t windowWidth,
        uint16_t windowHeight,
        bool fullScreen = false
    );

    void render();
    void update();
    SDL_Window* getWindow();
    bool handleEvents();

protected:


private:
    SDL_Window* window = nullptr;
    SDL_Renderer* renderer = nullptr;
    SDL_Event event;
    bool quit = true;

};

game.cpp:

#include "game.h"

bool Game::init()
{
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
        return true;
    else
        std::cout << "Could not initialise SDL" << '\n' << "Error: " << SDL_GetError() << std::endl;
}

bool Game::constructWindow(const char* windowName, uint16_t xWindowPos, uint16_t yWindowPos
    , uint16_t windowWidth, uint16_t windowHeight, bool fullScreen)
{
    window = SDL_CreateWindow(windowName, xWindowPos, yWindowPos, windowWidth, windowHeight, fullScreen);
    if (!window)
        std::cout << "Could not create window" << '\n' << "Error: " << SDL_GetError() << std::endl;

    return window;
}

void Game::render()
{
    renderer = SDL_CreateRenderer(window, -1, 0);
    if (!renderer)
        std::cout << "Failed to create a renderer" << '\n' << "Error: " << SDL_GetError() << std::endl;
}

void Game::update()
{
    SDL_RenderPresent(renderer);
}

SDL_Window* Game::getWindow()
{
    return window;
}

bool Game::handleEvents()
{
    while (SDL_PollEvent(&event))
        if (event.type == SDL_QUIT)
            quit = true;
    return quit;
}

我不确定 main 是否与问题有关,但无论如何:

#include "game.cpp"

int main(int argc, char* argv[])
{
    Game app;
    if (app.init())
        if (app.constructWindow("3D Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1200, 600))
            while (!app.handleEvents())
            {
                app.render();
                app.update();
            }

    SDL_DestroyWindow(app.getWindow());
    SDL_Quit();

}

I am not sure is main is related to the problem

哦,是的,是!:-)

通过将 game.cpp 包含在 main.cpp 中,您将 game.cpp 中的所有内容定义为 两次,main 中定义一次目标文件,一次在 game 目标文件中。目标文件对于实现而言 不是必需的 ,但它们很常见,可以用作解释。无论如何,您的错误消息提到 game.obj 的事实表明您的环境 确实 使用它们。

包含文件实际上只是将 #include 行替换为文件的内容,这解释了为什么两个目标文件最终具有相同的定义。

然后,当您 link 将两个目标文件放在一起时,瞧,符号定义了两次。

您通常不应将 cpp 文件包含到其他 cpp 文件中,因为它们倾向于 定义 您不想拥有多个副本的内容。相反,您应该包含 header 文件,这些文件往往只是 declare 东西。

这是一个重要的区别,我向学生解释如下。声明只是声明某物存在,而不是实际创建它。您可以根据需要多次执行此操作。另一方面,定义 使 它成为现实,而你真的只想做一次。

如果您想比我大大简化的解释提供的更多理解,one-definition rule 是您应该调查的内容。

#include "game.cpp"

你的问题是: 由于 #include(几乎)只是将给定文件复制并粘贴到 include 另一个文件的文件中。

这成为一个问题,因为在 C++ 中所谓的 一个定义规则 :您的 bool Game::init() 被允许 定义 一次,但由于包含 .cpp,实际上定义了两次。

这就是 header 的用途,您只需 声明 即可。由于 声明 而不是 定义 它两次就可以了,你可以安全地`包含它。