2012-01-19 92 views
4

我正在研究用C++編碼的遊戲,並且希望能夠在運行時更改語言。目前,該語言是由包含一個頭文件(其中有語言定義),像這樣在編譯時選擇:C++條件包含文件運行時

#include "lan_eng.h" 

因此,遊戲不允許一旦客戶端已編譯改變的語言。我的問題是,如果有一種方法可以在運行時有條件地包含文件?我是新的C++,所以起初我在想,我可以做這樣的事情:

#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 

肯定,使得它更容易維護,但問題是,我相信它只能在編譯時。我希望能夠將所選語言存儲在變量中(在運行時更改),然後使用該變量選擇要包含哪個頭文件。有沒有辦法做到這一點與頭文件,或者我會被迫做一個類?

我希望這不是一個愚蠢的問題;我的搜索沒有給我我期待的結果。

在此先感謝!

+1

預處理器是構建過程的第一個階段。所以,AFAIK,運行時包含頭文件可能是不可能的。 – Mahesh

回答

5

由於只在編譯期間對它們進行評估,因此不能在運行時更改#include。

你可以做什麼,而不是,有「語言表」。您可以構建一個您在運行時參考的系統,或者您可以在您想要更改語言時讀取和存儲多個文本文檔(如.xml文件)。這樣做也可以讓您的應用程序在將來被軟件用戶擴展,因爲它不會被硬編碼。

如果以這種方式進行設計,您可以將所有「語言表」保存在一個文件夾中,然後讓程序檢查該文件夾中是否有所有可用的語言表。這將允許用戶也添加語言到您的程序。

你基本上需要做的是創建一個字符串表,它可以作爲硬編碼方法的一部分,或作爲更動態方法的一部分(作爲語言表提到)。

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'; 
} 

[編輯]我從頭重寫了它,因爲我意識到純虛函數是錯誤在編譯的時候,如果你錯過一個句子的方式,使維護更簡單。這個版本還能夠整齊地處理變量(日期,名稱,時間,數字等)。這個概念是基於我們在我的工作中使用的,用於20多種語言的2900多個短語/句子。

+0

不幸的是,有很多階段需要翻譯,所以這個解決方案不適合。正如你所說,這對小項目很有好處。謝謝你的想法。 :) – Andy0708

0

在編譯前實際發生預處理(#include,#ifdef,#define等)。您可以將預處理視爲文本替換,其輸出是提供給編譯器的源代碼。 #defines等在你的程序中佔用了一個獨立的變量名稱空間,當你編譯程序的時候,所有這一切都是成立的。換句話說,你所要求的是不可能的。

爲了更好地理解這一點,請查看您的編譯器選項並查找可讓您保留預處理輸出的選項。

你需要做的是改變你的字符串處理的工作方式。不需要在編譯時更改字符串,而需要在運行時執行某些操作。

檢查您的平臺 - 在大多數平臺上都有用於本地化的API。不過,它們因平臺而異,所以如果您正在製作跨平臺應用程序,那麼您可能必須自行推出。

+0

謝謝 - 非常有用! :) – Andy0708