铸造字符* -> Q间距、可读性还是清晰度?(C++/夸提)

Casting char* -> QString, Readability or clarity? (C++/Qt)

本文关键字:清晰度 C++ 夸提 可读性 字符 gt 间距      更新时间:2023-10-16

我正试图将testclasses添加到现有的Qt项目中,遇到了这个问题:

void doSomething (QString str, int i) {..}
int main () {
    //Do I use
    doSomething("string", 0);
    //Or
    doSomething(QString("string"), 0);
}

如果我没有记错的话,它在内部也会这样做,因为它使用QString(char* c)构造函数隐式地强制转换char*

但哪种方式更可取?

我个人喜欢隐式转换,因为它比构造函数调用更容易阅读,但在我读过的C++书中,如果可能的话,应该避免隐式转换。

实际上,如果您使用Qt5,更好的方法是QStringLiteral()。它不仅表示意图(编译时常数QString),而且(略微)提高了效率,因为不需要从一些多字节编码到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函数传递参数这可能相当昂贵,因为它涉及内存数据的分配、复制和转换内部编码。

这可以通过进行来避免

if (node.hasAttribute(QStringLiteral("http-contents-length"))) //...

然后,QString的内部数据将在编译时生成,并且运行时不会发生转换或分配

使用QStringLiteral而不是双引号ascii literal可以大大加快了从上已知的数据创建QString的速度编译时。

如果编译器启用了C++11,字符串str实际上可以包含unicode数据。

实际上,在Qt的情况下,答案都不是。您应该使用QObject::tr()。您可能不需要在每个项目中进行翻译,但有正确的习惯要好得多,而不是稍后查看源代码并修复它

如果不需要转换该字符串,我建议使用QString静态函数QString::fromAscii()QString::fromLatin1()QString::fromLocal8Bit(),而不是隐式或显式强制转换:

int main () {
    doSomething( QString::fromAscii( "string" ), 0);
}

正如您所说,如果doSomething()方法的第一个参数是QString,那么如果您传递一个"const char*",则会初始化正确的对象,这更清楚、更容易阅读,结果也是一样的。

你的书中说你应该避免含蓄的选角,这是一个不错的建议。在C++中的许多情况下,您可能会被自动(和隐藏)行为弄糊涂。但是,如果您使用Qt框架编写程序,在大多数情况下,您可能会选择使用QString而不是std::string或char*。我认为隐式转换足够显式,不应该给你的发展带来任何麻烦。