When to use Q_NULLPTR?

2019-06-14 23:45发布

问题:

I see Q_NULLPTR being used liberally in Qt source code and examples, but I have found no documentation for what it is exactly and when it should be used.

For example in this official demonstration of the new Qt SerialBus module added in the new Qt v5.6:

if (!m_canDevice->connectDevice()) {
    delete m_canDevice;
    m_canDevice = Q_NULLPTR;

Did this serve the purpose of nullptr prior to that being added in C++11? If so, now that we have C++11, should I be using Q_NULLPTR?

PS: I tried searching the Qt source code for the definition of the macro but failed to find it.

回答1:

Did this serve the purpose of nullptr prior to that being added in C++11? If so, now that we have C++11, should I be using Q_NULLPTR?

Yes (somewhat) and No respectively.

C++ was quite lacking back in the days, so Qt had its own stuff, which later became obsolete as C++ caught up on the features.

That being said, Q_NULLPTR is (was) not functionally the same as nullptr, (as Andrei noted, if C++11 is supported it expands to nullptr) it didn't give you the type safety, just syntax "sugar". It illustrated the intent to the person reading the code, not to the compiler as nullptr does.



回答2:

Q_NULLPTR is a macro, that is replaced as nullptr if compiler supports c++11 and as NULL (which is replaced as 0) if it doesn't. If you use c++11, you can write nullptr instead; use NULL if you don't.



回答3:

Use Q_NULLPTR to stay compiler independent.

If you now decide to use nullptr, your code won't compile with an older c++98 compiler. If you decide to use NULL, you lose the c++11 type safety, even if available in your current compiler.

For the same reason macros like qMove(x) and the corresponding define Q_COMPILER_RVALUE_REFS exists.



回答4:

Actually Q_NULLPTR had only one purpose: To allow use of nullptr without loosing support for compilers which didn't have C++11/C++0x support, as a direct use of nullptr would result in errors in such setups. The downside is that there are ambiguities of its fallback to NULL (or 0 in older Qt versions) which might result in unintended runtime behavior and limit the supported use cases compared to nullptr.

In the rare case that you target non C++11 compliant compilers, use Q_NULLPTR but make sure that the code works well when C++11 features are disabled. In all other situations nullptr is the better alternative as it results in compilation errors instead of buggy runtime behavior when used with legacy compilers. Qt 5.7 and later dropped the support for compilation without C++11 so there is no need for Q_NULLPTR if you depend on those versions.

There are other features like qMove or Q_DECL_OVERRIDE that give improved semantic when used on supporting compilers without breaking compilation on older compilers.



标签: c++ qt c++11 null