obj/Debug/LevelLoader.o||In function `LevelLoader::LoadLevel(std::vector<Block, std::allocator<Block> >&, std::string)':|
/usr/include/c++/4.7/bits/vector.tcc|397|multiple definition of `LevelLoader::LoaderException'|
I found way around this, but I would like to know why it shows multiple declarations.
My solution is to declare this class in function body(void LoadLevel()), just before the throw statement. But why can't I define it inside my namespace, but outside function?
class LoaderException: public std::exception
{
virtualconstchar* what() constthrow()
{
std::string returned = "Error: loading levelfile was not successfull.";
return returned.c_str();
}
};
It probably should be:
1 2 3 4 5 6 7
class LoaderException: public std::runtime_error
{
LoaderException() :
std::runtime_error("Error: loading levelfile was not successfull.")
{
}
};
Look at line 20. That extra LoaderException after the closeing brace means you're not just defining the class, but actually instantiating a global object of that type within the namespace.
If you include this header file in more than one place, it means that the linker is seeing more than one attempt to create a global object with the same name. That's not legal.
Is there any particular reasion why you need your exception to be a global?
@kbw - I don't really know. It works fine the way it is, just class definition was forbidden there, and that's what I'm asking for. I'm using this pattern(so I just change class name and returned string) for few other objects, no complains and works as expected, but these were defined in other class body.
@Mikey - No. Okay, that explained it, I guess. So if I included LevelLoader.hpp in both LevelLoader.cpp and Level.hpp(some other header file), then it counts as creating this object twice, hence giving error?
So if I included LevelLoader.hpp in both LevelLoader.cpp and Level.hpp(some other header file), then it counts as creating this object twice, hence giving error?
Yes, exactly. It would be the same for any non-const global variable, regardless of type.
Having:
int myGlobalInt;
as a global variable in a header file would cause the same problem if the header were included in more than one file.
Note that, in C++, an exception is made for const globals. A const variable declared at namespace scope or global scope doesn't have external linkage - it's not truly global. You can safely put:
constint myGlobalConst = 17632;
in a header file and not cause linker problems. It's only non-const globals that cause problems in C++.
To be honest, you should use non-const globals as rarely as possible. They can cause all sorts of problems for your code.