2016-08-02 10 views
0

私は現在、設定ファイルから変数を読み込む関数を持っています。これらを使用して、一連の定数設定変数を初期化します。C++の設定ファイルからカスタムの "const"変数をロードするにはどうすればよいですか?

// header file 
namespace cfg { 
    extern const char *config_value; 
} 

// source file 
namespace cfg { 
    const char *config_value; 
} 

bool load_config() { 
    cfg::config_value = load_config_line("config_value"); 
} 

const char *load_config_line(const char *key) { 
     // read value from config.cfg... 
} 

これはかなりうまくいきます。問題は、このコードを他のいくつかのプロジェクトで再利用したいことです。つまり、定数値を変更する必要があります。これは、コード内の4つの異なる場所にあるconfig_valueの名前を変更することを意味します。また、私は、異なるプロジェクトで維持するために本質的に同じコードの複数のコピーを持っていることを意味します。

読み込みと解析に同じコードを使用して異なる値の定数値を設定する方法はありますか?おそらく、私がしなければならないのは、ヘッダファイルを変更するだけで、設定ファイルの値の名前が自動的に見つかるからです。面倒なことは、の外向きの設定値そのものが定数であり、コンパイル時に利用可能であることが理想です。(文字列と値のマップを使用するなどは望ましくありません。

+0

すでに実装されているシリアライザを使用して、ホイールを再作成してグローバル変数を処理する代わりに、struct/classインスタンスにデータを格納して再ロードする必要があります。 – Klaus

+0

@Klaus申し訳ありません "シリアライザ"について詳しく説明できますか? – Drgabble

+0

お気に入りの検索エンジンを使用してください:-)そこには、C++データ構造からファイル/ネットワーク/データベースにデータを読み書きする方法を提供するライブラリがたくさんあります。 http://www.boost.org/doc/libs/1_59_0_b1/libs/serialization/doc/index.html – Klaus

答えて

1

ここでの解決策は、グローバル変数を使用せず、ファイルからロードされた値で明示的に初期化するいくつかのsettings構造体を持つことです。 structインスタンス自体はconstである必要はありません(構築時にすべてを渡さない限り、値をロードする必要があります)が、すべてのアクセスはconstである必要があります。この最後のビットは、例えばsettingsを渡すことによって達成することができる。 const settings&を必要な場所に転送します。

int main() 
{ 
    // Variant A: 2-step init 
    settings s; 
    s.loadConfigFile(filename); 
    // Variant B: 1-step init - can make instance itself const 
    const settings s(filename); 

    Thing worker(s); // Thing::Thing(const settings&) 
    worker.work(); 
} 

もちろん、Workerはあなたの心が望むものであれば何でもかまいません。

struct settings 
{ 
    std::string config_value; 
} 

それは内に含まれる値へのアクセスを守る外部const次のとおりです。自分自身を設定

注一切の特別なconst性を必要としません。

+0

それは役に立つ、それはそこに私を得る。しかし、私はまだ新しい 'struct settings'(異なるプロジェクト内)ごとに' loadConfigFile'関数を書く必要がありますか?それは避けようとしているものです。任意の構造体が必要な場合は任意の構造体をとる 'loadConfigFile(設定セット、std :: stringファイル名)'が必要です – Drgabble

+0

@Drgabble任意の構造体が必要な場合は、例えば以下のような設定を保存する必要があります。 std :: unordered_map 'または' std :: unordered_map > 'のようなものです。構造体がある場合は、各設定構造体に対して別々の 'settings'構造体を必要とするかどうかを決定する必要があります。そのランタイムとプログラム時のトレードオフ。 – rubenvb

+0

同じ 'loadConfig()'関数を使って別々の 'settings'構造体を持つ方法はありませんか?はい、私はここに両方の​​世界のベストを得るために努力していますね...これを行う反射型の方法はありませんか?それとも、私はJavaで考えすぎですか? – Drgabble

関連する問題