c++ - 我可以在头文件中#define QStringLiterals 吗?

标签 c++ qt

看起来 C++ 编译器允许我在 C++ 头文件中#define QStringLiterals。像这样的东西:

// foo.h
#ifndef FOO_H
#define FOO_H

#define BAR QStringLiteral("bar")

#endif

目标是在包含 foo.h 的不同 .cpp 文件中使用(复制)BAR,这样我就可以避免多次键入 QStringLiteral (“栏”)

但是:

  • 安全吗? (我听说 QStringLiteral 会导致崩溃)
  • 它有效率吗? (即字符串是否只分配一次?)

最佳答案

不要那样做。

关于您的问题:

  • 安全吗? (我听说 QStringLiteral 会导致崩溃)

问题是为什么 QStringLiteral 可能会崩溃,答案与库和插件卸载有关。 QStringLiteral 创建一个引用静态有效负载(QString 自己的数据和实际字符串)的 QString。如果这个 QString 在库 A 中创建,传递给库 B,然后库 A 被卸载,B 就会留下一个危险的悬挂指针。 Qt 对此无能为力。

  • 它有效率吗? (即字符串是否只分配一次?)

完全没有:

  1. 您最终会在使用它的任何地方出现字符串文字数据。这可能会激增数据大小,或者对链接器施加更大的压力以跨多个 TU 合并相同的字符串文字数据。
  2. 由于 QStringLiteral 扩展为 lambda 表达式(...给定体面的编译器),您向编译器施加压力,使其在每次宏出现时解析并为 lambda 表达式生成代码
  3. 由于每个 lambda 必须传递一个唯一类型的对象,因此编译器无法轻易合并多个宏扩展——即使在同一个 TU 中。直到最近,优化器才开始折叠相同的二进制代码。

解决方案:写一个外联函数:

// foo.h
#ifndef FOO_H
#define FOO_H

QString bar();

#endif

// foo.cpp
#include "foo.h"
QString bar() {
    return QStringLiteral("bar");
}

关于c++ - 我可以在头文件中#define QStringLiterals 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36424321/

相关文章:

c++ - Qt (c++) - 是否可以使用信号从方法返回?

c++ - c++ vector<vector<int>> 如何管理内存

c++ - 在qml中显示、更改数据并保留QQmlListProperty

c++ - 为什么std::abs()不能与 float 一起使用

c++ - 如何连接通过 cython 返回对象引用的 C++ 函数

c++ - 如何退出 QThread::wait()

c++ - 在 Linux 上为 Qt 应用程序获取 root 访问权限的正确方法

c++ - QT中如何自定义 "Notification Web API"

c++ - 在 linux 上安装 cpp 库

c++ - boost::in_place 将参数作为 const refs