我试图将testclasses
添加到现有的Qt项目中,我遇到了这个问题:
void doSomething (QString str, int i) {..}
int main () {
//Do I use
doSomething("string", 0);
//Or
doSomething(QString("string"), 0);
}
如果我没有弄错,它会在内部执行相同操作,因为它会char*
隐式地使用QString(char* c)
构造函数。
但哪种方式更受欢迎?
我个人喜欢隐式演员,因为它比构造函数调用更容易阅读,但在我读过的C ++书中,如果可能的话,应该避免隐式转换。
答案 0 :(得分:3)
实际上,如果您使用Qt5,更好的方法是QStringLiteral()
。它不仅表示intent(编译时常量QString
),而且(稍微)提高效率,因为不需要从某些mulitbyte编码到UTF-16的运行时转换。
如果您需要使用Qt4,请自行有条件地定义:
#ifndef QStringLiteral
#define QStringLiteral(x) (QString::fromUtf8(x))
#endif
或者如Kuba Ober评论,添加
lessThan(QT_MAJOR_VERSION, 5): DEFINES += QStringLiteral=QString::fromUtf8
到您的.pro文件。
引自Qt文档:
宏在编译时从str生成QString的数据 如果编译器支持它。从中创建QString是免费的 在这种情况下,生成的字符串数据存储在只读状态 编译对象文件的一部分。
对于不支持创建编译时字符串的编译器, QStringLiteral将回退到QString :: fromUtf8()。
如果您的代码如下:
if (node.hasAttribute("http-contents-length")) //...
将创建一个临时QString作为hasAttribute函数传递 参数。这可能非常昂贵,因为它涉及内存 分配和复制以及将数据转换为QString 内部编码。
这可以通过
来避免
if (node.hasAttribute(QStringLiteral("http-contents-length"))) //...
然后QString的内部数据将在编译时生成 在运行时不会发生转换或分配
使用QStringLiteral而不是双引号ascii文字可以 显着加快从已知数据创建QString的速度 编译时间。
如果编译器启用了C ++ 11,则字符串str实际上可以包含 unicode数据。
答案 1 :(得分:2)
实际上在Qt的情况下,答案都不是。您应该使用QObject::tr()
代替。你可能不需要在每个项目中进行翻译,但要有正确的习惯要好得多,而不是稍后查看源代码并修复它。
如果不需要翻译该字符串,我建议使用QString
static functions QString::fromAscii()
,QString::fromLatin1()
或QString::fromLocal8Bit()
代替隐式或显式广告:< / p>
int main () {
doSomething( QString::fromAscii( "string" ), 0);
}
答案 2 :(得分:0)
正如你所说,如果doSomething()方法的第一个参数是QString,如果传递'const char *',则会初始化正确的对象,这更清晰,更容易阅读,结果是相同。
你的书说你应该避免隐式演员,这不是一个糟糕的建议。在许多情况下,在C ++中,您可能会对自动(和隐藏)行为感到困惑。但是如果使用Qt框架编写程序,在大多数情况下,您可能会选择使用QString而不是std :: string或char *。我认为隐式转换是非常明确的,不应该在开发过程中造成任何麻烦。