C ++条件包含文件运行时

时间:2012-01-19 17:17:20

标签: c++ include

我正在开发一个用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

确保维护更容易,但问题是我相信它只能在编译时运行。我希望能够将所选语言存储在变量中(在运行时更改),然后使用该变量来选择要包含的头文件。有没有办法用头文件做这个,或者我会被迫做一个类?

我希望这不是一个愚蠢的问题;我的搜索没有给我我希望的结果。

提前致谢!

4 个答案:

答案 0 :(得分:5)

由于仅在编译期间评估#include,因此无法在运行时更改#include。

你可以做的是拥有“语言表”。您可以构建在运行时引用的系统,也可以在需要更改语言时读取和存储多个文本文档(如.xml文件)。这样做也可以让您的应用程序在将来被软件用户扩展,因为它不会被硬编码。

如果您以这种方式进行设计,可以将所有“语言表”保存在一个文件夹中,然后让程序检查所有可用语言表的文件夹。这将允许用户也为您的程序添加语言。

您基本上需要做的是创建一个字符串表,可以作为硬编码方法的一部分,或作为更动态的方法的一部分(作为语言表提到)。

答案 1 :(得分:3)

你不能用#include来做,那只是编译时间。更具体地说,这只是预处理器,它在编译之前发生。

要获得运行时变化,您必须将翻译移动到文本文件(类似于xml,但纯文本也可以),并设置一个系统,在启动时加载文件以填充字符串需要翻译的代码。

这也意味着所有字符串在启动时都会动态调整大小,因此代码的初始化周期会增加。但这有时是灵活性的代价。

答案 2 :(得分: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多个短语/句子。

答案 3 :(得分:0)

预处理(#include,#ifdef,#define等)实际上是在编译之前发生的。您可以将预处理视为文本替换,其输出是提供给编译器的源代码。 #defines等会占用程序中变量的单独命名空间,并且在编译程序时,所有这些都是一成不变的。换句话说,你所要求的是不可能的。

为了更好地理解这一点,请查看编译器选项并查找允许您保留预处理输出的选项。

您需要做的是改变字符串处理的工作方式。您无需在编译时更改字符串,而是需要在运行时执行某些操作。

检查您的平台 - 在大多数平台上都有用于进行本地化的API。但是,它们因平台而异,所以如果您正在使用跨平台应用程序,那么您可能需要自己动手。