2012-01-19 13 views
4

私はC++でコーディングされたゲームを開発中で、実行時に言語を変更できるようにしたいと考えています。現在、言語がそうのように、ヘッダファイルを(言語定義を有する)を含むことにより、コンパイル時に選択されます。C++の条件付きインクルードファイルランタイム

#include "lan_eng.h" 

そのため、ゲームは、クライアントがコンパイルされた後の言語を変更することはできません。私の質問は、実行時に条件付きでファイルを含めることができる方法があるかどうかです。維持することが容易になりますが、問題は、私はそれはコンパイル時にのみ動作すると信じていることである

#define DEF_LANGUAGE_ENG 
//#define DEF_LANGUAGE_DEN 

#ifdef DEF_LANGUAGE_ENG 

    #include "lan_eng.h" 

#endif 

#ifdef DEF_LANGUAGE_DEN 

    #include "lan_den.h" 

#endif 

確かに:私はこのような何かを行うことができると考えていた最初のように、私は、C++に新しいです。選択した言語を実行時に変更される変数に格納し、その変数を使用してどのヘッダーファイルを含めるかを選択できます。ヘッダーファイルでこれを行う方法はありますか、クラスを作ることを余儀なくされますか?

私はそれが愚かな質問ではないことを願っています。私の検索は、私が望んでいた結果を私に与えてくれませんでした。

ありがとうございます!

+1

プリプロセッサは、ビルドプロセスの第1段階です。したがって、AFAIK、実行時のヘッダーのインクルードは不可能かもしれません。 – Mahesh

答えて

5

コンパイル時にのみ評価されるため、実行時に#includeを変更することはできません。

代わりにできることは、「言語シート」です。実行時に参照するシステムを構築することも、言語を変更するときに読み込んで保存するテキストドキュメント(.xmlファイルなど)を複数作成することもできます。このようにすることで、ハードコードされていないため、将来的にソフトウェアのユーザーがアプリケーションを拡張することもできます。

このように設計すると、すべての「言語シート」を1つのフォルダに保存しておき、利用可能なすべての言語シートをそのフォルダでチェックするようにプログラムを設定できます。これにより、ユーザーはプログラムに言語を追加することもできます。

基本的には、ハードコードされたメソッドの一部として、またはよりダイナミックなメソッド(言語シートとして言及される)の一部として行うことができる文字列テーブルを作成する必要があります。

3

#includeで行うことはできません。コンパイル時のみです。より具体的には、これはプリプロセッサのみであり、コンパイル前に発生します。

ランタイムバリエーションを取得するには、翻訳ファイルをテキストファイル(おそらくxmlのようなものですが、プレーンテキストも使用できます)に移動して、起動時にファイルをロードして文字列を取り込むシステムをセットアップする必要があります翻訳が必要なコードで

これはまた、起動時にすべての文字列が動的にサイズ変更されるため、コードの初期化期間が長くなることを意味します。しかしそれは時々柔軟性のコストです。

3

おそらく、私が考えてきた最も簡単な方法は次のとおりです。

struct language { 
    virtual str::string greeting() =0; 
    virtual str::string greeting(const std::string& name) =0; 
    virtual str::string goodbye() =0; 
    virtual ~language() {} 
}; 
struct English_language { 
    virtual str::string greeting() {return "Hello";} 
    virtual str::string greeting(const std::string& name) {return "Hello "+name;} 
    virtual str::string goodbye() {return "Goodbye";} 
} English; 
struct German_language { 
    virtual str::string greeting() {return "Hallo";} 
    virtual str::string greeting(const std::string& name) {return name+" Hallo";} 
    virtual str::string goodbye() {return "Auf Wiedersehen";} 
} German; 
language* CurLanguage = &English; 

int main() { 
    std::cout << CurLanguage->greeting("Steve") << '\n'; 
    CurLanguage = &German; 
    std::cout << CurLanguage->goodbye() << '\n'; 
} 

[EDIT]私はあなたが文を逃した場合、純粋仮想関数は、コンパイル時にエラーにする方法です実現ので、私は、最初から書き直しメンテナンスがずっと簡単になりました。このバージョンには、変数(日付、名前、時刻、数字など)をきれいに処理する機能もあります。このコンセプトは私が仕事で使うものに基づいており、約20の言語で2900以上のフレーズ/センテンスが使用されています。

+0

残念ながら、翻訳する段階はたくさんあるため、この解決策は適切ではありません。あなたが言うように、それは小規模なプロジェクトには良いことです。アイデアをありがとう。 :) – Andy0708

0

前処理(#include、#ifdef、#defineなど)は実際にはコンパイル前に発生します。前処理はテキスト置換と考えることができ、その出力はコンパイラに供給されるソースコードです。 #definesなどは、プログラム内の変数とは別の名前空間を占有します。プログラムがコンパイルされるまでには、すべてが石で設定されます。言い換えれば、あなたが求めているのは不可能です。

これをよりよく理解するには、コンパイラオプションを調べて、前処理された出力を保持できるオプションを探します。

代わりに行う必要があるのは、文字列の処理方法の変更です。コンパイル時に文字列を変更する代わりに、実行時に何かをする必要があります。

ほとんどのプラットフォームでは、ローカライズのためのAPIが用意されています。ただし、プラットフォームによって異なります。クロスプラットフォームアプリを使用している場合は、自分でロールバックする必要があります。

+0

ありがとう - 非常に便利! :) – Andy0708