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 的用途,您只需 声明 即可。由于 声明 而不是 定义 它两次就可以了,你可以安全地`包含它。
我正在设置我的第一个正确的 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 的用途,您只需 声明 即可。由于 声明 而不是 定义 它两次就可以了,你可以安全地`包含它。