何时使用Q_NULLPTR?

21

我在Qt源代码和示例中经常看到使用 Q_NULLPTR,但是我没有找到确切的文档说明它是什么以及应该何时使用。

例如,在新的Qt v5.6中添加的Qt SerialBus模块的这个官方 演示 中:

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

在C++11中添加nullptr之前,这是否已经达到了原本的目的?如果是这样的话,既然我们现在有了C++11,那么我应该使用Q_NULLPTR吗?

PS:我尝试搜索Qt源代码以查找宏定义,但未能找到。

4个回答

22

Q_NULLPTR是一个宏,在C++11编译器中会替换为nullptr,而在不支持C++11的编译器中会替换为NULL(NULL又会被替换成0)。如果您使用C++11编译器,可以直接使用nullptr;如果不是,请使用NULL


5
如果有人需要证明,这里是源代码 - thuga

19

在C ++11之前,这是否是nullptr的用途?如果是,既然我们有了C ++11,我应该使用Q_NULLPTR吗?

是的(有点),分别为否。

C ++在过去相当缺乏功能,因此Qt拥有自己的东西,后来随着C++增加了这些功能,这些东西变得过时了。

尽管如此,Q_NULLPTRnullptr在功能上(曾经)不完全相同(正如Andrei所指出的,如果支持C++11,则会扩展为nullptr),它没有为您提供类型安全性,只是语法“糖”而已。它向阅读代码的人说明了意图,而并非像nullptr一样向编译器说明。


3
实际上,Q_NULLPTR 只有一个目的:允许使用 nullptr 而不失去对没有 C++11/C++0x 支持的编译器的支持,因为在这种情况下直接使用 nullptr 会导致错误。缺点是在回退到 NULL(或旧版 Qt 中的 0)时存在歧义,可能会导致意外的运行时行为,并限制与 nullptr 相比支持的用例。
在极少数情况下,如果您的目标是非 C++11 兼容的编译器,请使用 Q_NULLPTR,但要确保当禁用 C++11 特性时代码能够正常工作。在所有其他情况下,nullptr 是更好的选择,因为它在与旧编译器一起使用时会导致编译错误而不是出现错误的运行时行为。Qt 5.7 及更高版本不再支持无需 C++11 编译,因此如果您依赖这些版本,则不需要 Q_NULLPTR
还有其他功能,例如在支持的编译器上使用时具有改进的语义的 qMoveQ_DECL_OVERRIDE,而在旧编译器上不会破坏编译。

2

使用Q_NULLPTR可以保持编译器的独立性。

如果您现在决定使用nullptr,则您的代码将无法与旧的c++98编译器一起编译。如果您决定使用NULL,即使您当前的编译器支持c++11类型安全,也会失去它。

出于同样的原因,像qMove(x)和相应定义Q_COMPILER_RVALUE_REFS这样的宏存在。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接