Reputation: 2328
I want to write a little game using OpenGL and I have a FileUtils.hpp
with a ReadFile
-function and I have a class ShaderProgram
which handles shaders and uses FileUtils
.
Now, when I want to start the program I get this error:
ShaderProgram.obj : error LNK2005: "
class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl ReadFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)
" (?ReadFile@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV12@@Z) already defined in Main.obj
I have not much experience with C++ but I think this error tells me, that my ReadFile
function is defined twice. This should happen if you include a header-file twice which has no #pragma once
or header-guard.
My FileUtils.hpp
looks like this:
#pragma once
#include <string>
#include <iostream>
#include <fstream>
std::string ReadFile(const std::string& fileName)
{
// File reading is done here.
// Not important for this question.
}
My ShaderProgram
includes this header:
#pragma once
#include <string>
#include <GLEW\glew.h>
#include "FileUtils.hpp"
// Shader stuff done here
And my Main.cpp
includes ShaderProgram.hpp
:
#include "ShaderProgram.hpp"
#include "Window.hpp"
#define WIDTH 800
#define HEIGHT 600
#define TITLE "Voxelworld"
#define VERTEX_SHADER_FILE "voxelworld.v.glsl"
#define FRAGMET_SHADER_FILE "voxelworld.f.glsl"
using namespace voxelworld;
int main(int argc, char *argv[])
{
Window window = Window(WIDTH, HEIGHT, TITLE);
ShaderProgram shaderProgram = ShaderProgram(VERTEX_SHADER_FILE, FRAGMET_SHADER_FILE);
while (!window.IsCloseRequested())
{
shaderProgram.Use();
window.Update();
shaderProgram.StopUse();
}
return 0;
}
Window.hpp
includes neither FileUtils.hpp
nor ShaderProgram.hpp
.
I am pretty sure I just made a silly mistake somewhere, but I don't know where.
Upvotes: 0
Views: 64
Reputation: 2416
With no class or namespace wrapped around it, ReadFile might be conflicting with the ReadFile in WinBase.h. WinBase.h often ends up deep in your include tree.
Upvotes: 0
Reputation: 409176
Unless the function is small enough to hopefully be inlined (in which case you should mark it as such) then don't define functions in header files, only declare them.
So in the header file do e.g.
std::string ReadFile(const std::string& fileName);
Then in one source file do the full definition:
std::string ReadFile(const std::string& fileName)
{
...
}
The problem you have now is that the function will be defined in all source files (translation units) where you include the header file.
Upvotes: 3