Casting char * & # 8594; QString, readability or clarity? (C ++ / Qt)

I am trying to add testclasses

to an existing Qt project and I came across this question:

void doSomething (QString str, int i) {..}

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

      

If I am not mistaken, it does the same internally as it char*

uses a constructor implicitly QString(char* c)

.

But which way is preferable?

I personally like implicit pronunciation as it is easier to read than calling a constructor, but I read in my C ++ book that implicit casting should be avoided whenever possible.

+3


source to share


3 answers


In fact, if you are using Qt5, the best approach is QStringLiteral()

. This not only means intent (compile-time constant QString

), but also (slightly) increases efficiency, because no run-time conversion is required from some mulitbit encoding to UTF-16.

If you need to use Qt4, then conditionally defines it yourself:

#ifndef QStringLiteral
#define QStringLiteral(x) (QString::fromUtf8(x))
#endif

      

Or, as Cuba Aubert commented, add

lessThan(QT_MAJOR_VERSION, 5): DEFINES += QStringLiteral=QString::fromUtf8

      

to your .pro file.



Quoting from Qt Documentation:

The macro generates data for a QString from str at compile time if the compiler supports it. Creating a QString from it is free this case, and the generated string data is saved in a read-only segment of the compiled object file.

For compilers that do not support compile-time string generation, QStringLiteral will fall back to QString :: fromUtf8 ().

If you have code similar to:

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

      

A temporary QString will be created and passed as the hasAttribute parameter. This can be quite expensive as it involves memory allocation and copying and converting data to QString internal encoding.

This can be avoided by doing

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

      

Then the internal QString data will be generated at compile time and no conversion or allocation will occur at startup

Using a QStringLiteral instead of a double quoted ascii literal can significantly speed up the creation of a QString from the data known at compile time.

If the compiler is C ++ 11 enabled, the str string may actually contain unicode.

+3


source


Actually, in the case of Qt, the answer is not. You should use instead QObject::tr()

. You may not need a translation in every project, but it is much better to have the right habit rather than review the source later and fix it.

If translation of this line is not required, I recommend using static functions , or instead of implicit or explicit actuation:QString

QString::fromAscii()

QString::fromLatin1()

QString::fromLocal8Bit()



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

      

+2


source


As you said, if the first parameter of the doSomething () method is QString, the right object will be initialized, if you pass a 'const char *', it becomes clearer, easier to read and the result is the same.

Your book says you should avoid implicit casting and that is not bad advice. In many cases in C ++, you are likely to be confused by the automatic (and hidden) behavior. But if you are writing a program using Qt frameworks, you might want to use QString instead of std :: string or char * in most cases. I think the implicit conversion is explicit enough and shouldn't cause any problems in your development.

0


source







All Articles