1

我正在用 C++ 开发一堆 Qt 应用程序,它们都使用一些模块(翻译单元)来实现也使用 Qt 的常见功能。

每当我将 C 字符串(隐式转换)或 C++ 字符串对象(fromStdString())转换为 QString 对象时,我希望原始数据是 UTF-8 编码的,反之亦然(toStdString())。

由于默认值是 Latin-1,我必须将编解码器“手动”(在我的每个程序的初始化过程中)设置为 UTF-8:

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8"));

并非我的所有模块都有初始化过程。包含一个类的那些(我可以把这一行放在类构造函数中),但有些模块只包含一个带有很多函数的命名空间。所以 setCodecForCStrings() 没有位置。每当我隐式地从/转换为 QString 时(从我的一个模块中),我依赖于已经由主程序的 init 过程设置的编解码器,这似乎是一个相当糟糕的解决方案。

有没有一种可靠的方法可以在我的模块中将编解码器设置为 UTF-8,还是我必须非常小心不要使用隐式转换(至少在我的模块中)并编写类似 std::string(q .toUtf8().constData()) 而不是 q.toStdString()?

4

1 回答 1

3

这可以使用自动实例化的单例类的类定义来完成,该类在其构造函数中有一些初始化代码:

class ModuleInit {
    static ModuleInit *instance;
public:
    ModuleInit() {
        QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8"));
    }
};
ModuleInit * ModuleInit::instance = new ModuleInit(); // put this line in .cpp!

将此代码放在任何项目中的任何位置都会将文本编解码器设置为 UTF-8 。但是,您可以覆盖 main() 方法中的文本编解码器,因为上面的代码甚至main() 方法之前执行。

对于“任何地方”,我当然是指在语法上允许的地方。将类定义放在某个头文件中,并将实例化放在适当的 .cpp 文件中。

您甚至可以将整个代码放在一个 .cpp 文件中,说明moduleinit.cpp您编译和链接的文件,但从不明确使用(没有可以包含的头文件......)。这也将避免除了第一个实例之外的意外实例化,并且您不会遇到重复类名的任何问题。

请注意,您不能在一个特定文件中为 C 字符串设置编解码器。使用设置编解码器QTextCodec::setCodecForCString将在应用程序范围内设置它!

于 2012-07-08T17:46:35.027 回答