20

私の目標は、私が取り組んでいる C++ ゲームでグローバル定数を使用することです (グラフィック情報などを表すため)。私の現在の実装では、それらをすべて .h に入れ、どこにでも含めます。これは機能しますが、設定を変更するたびにコード ベース全体を再コンパイルする必要があります。

したがって、私の次のアイデアは、それらをいくつかの構成txtファイルに投げ込んで解析することでした。これにより、設定が変更されたときにコードが実際に変更されることはありません。パーサーは十分に単純で、値を定数に入れることができましたが、パーサーがコード ブロックだったため、定数はもはやグローバルではありませんでした。

これを解決する良い方法はありますか?おそらく、ブロック内にあるにもかかわらずそれらをグローバルにする方法や、設定を変更するときにすべてを再コンパイルしないようにする方法はありますか?

4

4 に答える 4

25

The way I used solve this is to put the variables in a separate global namespace, which is in a header file named something like config.h, then include that file everywhere.

// In config.h

#ifndef CONFIG_H
#define CONFIG_H

namespace config
{
    extern int some_config_int;
    extern std::string some_config_string;

    bool load_config_file();
}

#endif

The in a source file, you define the variable and also set them to a default value. This source file also have the code to load the variables from your configuration file.

// In config.cpp

namespace config
{
    int some_config_int = 123;
    std::string some_config_string = "foo";
}

bool config::load_config_file()
{
    // Code to load and set the configuration variables
}

Now in every source file you need the configuration variables, include config.h and access them like config::some_config_int.

However, there is no "proper" way of solving this, all ways that work are proper in my eyes.

于 2012-06-05T06:17:22.390 に答える
19

これを行う別の方法は、シングルトン クラスを作成することです。

#include <fstream>
#include <map>
#include <string>

class ConfigStore
{
public:
    static ConfigStore& get()
    {
        static ConfigStore instance;
        return instance;
    }
    void parseFile(std::ifstream& inStream);
    template<typename _T>
    _T getValue(std::string key);
private:
    ConfigStore(){};
    ConfigStore(const ConfigStore&);
    ConfigStore& operator=(const ConfigStore&);
    std::map<std::string,std::string> storedConfig;
};

ここで構成はマップに保存されます。つまり、parseFile がファイルを読み取り、getValue が型を解析できる限り、新しいキーを追加した場合に構成クラスを再コンパイルする必要はありません。

使用法:

std::ifstream input("somefile.txt");
ConfigStore::get().parseFile(input);
std::cout<<ConfigStore::get().getValue<std::string>(std::string("thing"))<<std::endl;
于 2012-06-05T08:11:06.593 に答える