Frage

MainGame.h

#ifndef MainGame_h
#define MainGame_h

#include <string>
#include <sstream>
#include "Horde3D.h"

//definitions

#endif MainGame_h

MainGame.cpp

#include <math.h>
#include <iomanip>
#include "Horde3DUtils.h"
#include "MainGame.h"
#include "GameConfig.h" //<--

//code

main.cpp

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>

#include "glfw.h"
#include "MainGame.h"
#include "GameConfig.h" //<--

//code

GameConfig.h

#ifndef GameConfig_h
#define GameConfig_h

#include <string>
#include <sstream>

#define MAX_PATH 260

class GameConfig
{
    static std::string ExtractStartupPath(char *full_app_path)
    {
        const std::string s(full_app_path);

        if(s.find( "/" ) != std::string::npos)
            return s.substr( 0, s.rfind( "/" )) + "/";
        else if(s.find( "\\" ) != std::string::npos )
            return s.substr( 0, s.rfind( "\\" )) + "\\";
        else
            return "";
    }

public:
    static bool IsFullScreen;
    static int StatMode;
    static int FreezeMode;
    static bool DebugViewMode;
    static bool WireframeMode;
    static char *GameTitle;
    static int WindowWidth, WindowHeight;
    static char StartupPath[MAX_PATH];
    static char ContentPath[MAX_PATH];

    static void Initialize(char *startup_path)
    {
        GameTitle = "TestGame\0";

        std::string startup_dir = ExtractStartupPath(startup_path);
        memcpy(StartupPath, startup_dir.c_str(), startup_dir.length() * sizeof(char));

        std::string path(StartupPath);
        path.erase(path.find_last_of('\\'), std::string::npos);
        path.append("\\Content");
        memcpy(ContentPath, path.c_str(), path.length() * sizeof(char));
    }
};

int GameConfig::StatMode = 0;
int GameConfig::FreezeMode = 0;
bool GameConfig::DebugViewMode = false;
bool GameConfig::WireframeMode = false;
bool GameConfig::IsFullScreen = false;
int GameConfig::WindowWidth = 800;
int GameConfig::WindowHeight = 600;
char GameConfig::StartupPath[MAX_PATH] = { 0 };
char GameConfig::ContentPath[MAX_PATH] = { 0 };
char *GameConfig::GameTitle = "TestGame\0";

#endif GameConfig_h

When compiling it I getting linker errors...

main.obj : error LNK2005: "public: static int GameConfig::StatMode" (?StatMode@GameConfig@@2HA) is already define in в MainGame.obj

But I don't understand why... There are only two includes of GameConfig - one in MainGame.cpp and second in main.cpp. Those should never cross. And even if they crossed, what #ifndef GameConfig_h, #define GameConfig_h and #endif GameConfig then for?

I use VC++ 2010 Express Edition

War es hilfreich?

Lösung 2

You need to move initialisation of the statics to GameConfig.cpp.

Each source file which includes GameConfig.h is picking up a their own copy of these variables at present.

Andere Tipps

Include guards help you avoid including the same file more than once from the same translation unit. However, since the translation units are processed independently, both of them will get the included code, and therefore produce duplicate definitions.

To avoid this problem you need to move definitions out of the header and into a CPP file:

GameConfig.cpp:

#include "GameConfig.h"

int GameConfig::StatMode = 0;
int GameConfig::FreezeMode = 0;
bool GameConfig::DebugViewMode = false;
bool GameConfig::WireframeMode = false;
bool GameConfig::IsFullScreen = false;
int GameConfig::WindowWidth = 800;
int GameConfig::WindowHeight = 600;
char GameConfig::StartupPath[MAX_PATH] = { 0 };
char GameConfig::ContentPath[MAX_PATH] = { 0 };
char *GameConfig::GameTitle = "TestGame\0";

The instanciations of your static members shouldn't be in the .h file but in the corresponding .cc file.

Otherwise they are instantiated in every compilation unit.

Include guards are only useful inside a single compilation unit (ie one single cpp file). Since the cpp files are compiled separately, for each file the include guard will start as undefined and therefore the .h file will be included twice, once for each cpp file. If the .h file includes for example a function definition, it will be defined twice.

Normally you make the problem "go away" by putting only declarations in the h files, and actually defining the functions in cpp files. That way, the function will only be defined once.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top