如何定义全局常量(Q)字符串?

时间:2018-11-27 09:09:17

标签: c++ qt initialization global-variables

有时需要魔术弦,例如访问INI文件,注册表,REST API等时...

我们假设一个JSON密钥“用户名”:

如何定义此选项...

  1. #define JSON_USERNAME "username"
  2. #define JSON_USERNAME (QString("username"))
  3. #define JSON_USERNAME (QStringLiteral("username"))
  4. QString const JSON_USERNAME("username")
  5. QStringLiteral const JSON_USERNAME("username")
  6. QLatin1String const JSON_USERNAME("username")

或7。:

QString JSON_USERNAME() {
    static QString const str("username");
    return str;
}

需要与括号一起使用:JSON_USERNAME()

...仅举几例。

让我们假设这个简单的用例:

// (cpp-file-)global definition of JSON_USERNAME = ("username")

bool hasUsername(QJsonObject &jo) {
    return jo.contains(JSON_USERNAME);
}
QString getUsername(QJsonObject &jo) {
    return jo.value(JSON_USERNAME).toString();
}
void setUsername(QJsonObject &jo, QString const &name) {
    jo.insert(JSON_USERNAME, name);
}

所以有:

  • 多次出现:每个功能一次
  • 频繁调用:在从JSON解析到/时
  • 许多不同的字符串:每个键一个

考虑到QString("...")执行from-UTF-8转换并且QString被隐式共享,上述每种方法都有其缺点:

  1. 每次通话(开销)为UTF-8转换
  2. 与1相同
  3. 编译时初始化,但在每个地方都使用(更大的二进制文件)

4.-6。具有未指定实例化的全局变量

  1. pro:延迟初始化,单个共享实例,相反:需要括号(不直观)

是否存在(特定于Qt的)方法

  • 类似于令牌(可以像变量一样使用)
  • 是惰性初始化的,
  • 几乎没有二进制开销(例如const char *),并且
  • 几乎没有运行时开销(例如const QString)?

1 个答案:

答案 0 :(得分:0)

我无法参考全球指南,但会投票赞成。 1。

原因:config应该保持为config。 出于以下原因,应避免将任何类型的配置与可执行代码混合使用:

  • 您可能希望明天将所有配置移至某种yaml / json
  • 有时配置会移至cmake或其他工具箱。想象一下,您强迫您的未来贡献者使用'QString(“ aa”)'这样的值填充CMAKE变量
  • 配置应独立于实现-您的用户名不取决于QString / QLatin1String或您要使用的任何内容
  • 可以在应用程序的不同模块之间共享
  • Config,这些模块可以对其进行不同的使用。
  • 可执行的全局代码...如果我们谈到转换utf-8,它对性能的提升几乎没有,但是您将陷入与实例生存期相关的其他问题。