看起来C ++编译器允许我在C ++头文件中#define
QStringLiterals。类似的东西:
// foo.h
#ifndef FOO_H
#define FOO_H
#define BAR QStringLiteral("bar")
#endif
目标是在包含BAR
的不同.cpp文件中使用(复制)foo.h
,这样我就可以避免多次输入QStringLiteral("bar")
。
可是:
答案 0 :(得分:5)
不要这样做。
关于你的问题:
问题是为什么 QStringLiteral可能崩溃,答案与库和插件卸载有关。 QStringLiteral创建一个QString,它引用静态的有效负载(QString自己的数据和实际的字符串)。如果在库A中创建此QString,传递给库B,然后卸载库A,则B将留下危险的悬空指针。 Qt在这里无能为力。
完全没有:
解决方案:写一个离线函数:
// foo.h
#ifndef FOO_H
#define FOO_H
QString bar();
#endif
和
// foo.cpp
#include "foo.h"
QString bar() {
return QStringLiteral("bar");
}
答案 1 :(得分:1)
我可以#define头文件中的QStringLiterals吗?
你可以,但你不应该,正如其他答案中所解释的那样。
另一种方法是使用全局字符串常量,使用可区分的前缀来避免全局命名空间污染。您也可以将它们放入命名空间:
// bar.h
#pragma once
#include <QString>
extern const QString kBar; // approach 1
namespace K {
extern const QString bar; // approach 2
}
// bar.cpp
#include "bar.h"
const QString kBar { QStringLiteral("bar"); }
const QString K::bar { QStringLiteral("bar"); }
// main.cpp
#include "bar.h"
int main() {
qDebug() << kBar << K::bar;
}
如果您担心初始化顺序,那么在输入main()
之前,只需假定值未定义;让main()
显式实例化依赖于这些常量的所有内容。你应该以这种方式编码,所以这在实践中不应该是一个问题。