nullptr与__nullptr的区别

12

我想知道为什么有两种指定空指针的方式。我看了这个链接,但并没有很清楚地理解它的用途。

有人可以给一个好的例子什么时候使用什么吗?

3个回答

25

自2005年起,C++/CLI语言已经拥有了nullptr关键字。 当C++11采用nullptr关键字用于C++时,这就导致了问题。现在有两个关键字,一个用于托管代码,另一个用于本机代码。 C++/CLI编译器可以编译两者。因此,当您指的是本机空指针时,必须使用__nullptr,而当您指的是托管空指针时,请使用nullptr。

只有在启用/clr编译选项时才相关。 换句话说,以C++/CLI代码编写。 在C++代码中只需使用普通的nullptr即可。


我认为关于/clr的内容可能是这个答案中最重要的部分。如果你不担心将你的C++代码与.NET框架连接起来,那么你应该始终使用nullptr - Michael Price
说实话,即使在C++11出现之前,将C++代码移植到C++/CLI中已经是一个问题(尽管很少有相关性)。 - Deduplicator
我在一个C++/CLI应用程序中遇到了同样的问题。Hans的解释清楚地说明了问题的来源。但是,在我的情况下,代码使用了try/catch块。然而,错误并没有在我的代码中标记,而是在一个名为"exception"(没有扩展名)的Microsoft包含文件中,在六个类似这样的位置: - undefined
exception_ptr(nullptr_t) noexcept { __ExceptionPtrCreate(this); } 该文件来自VC工具集。 - undefined

1
这是一个关于IT技术的翻译。以下是需要翻译的内容:

这个案例中,微软写了一个很好的解释(https://learn.microsoft.com/en-us/cpp/extensions/nullptr-cpp-component-extensions?view=msvc-170)- 和这个帖子中所接受的答案完全一致:“在本机代码中使用nullptr,在C++/CLI中对管理对象使用nullptr,在本机指针中使用__nullptr”。

然而,在同一篇文章中,微软展示了一些例子,完全忽略了这个建议:

// mcpp_nullptr.cpp
// compile with: /clr
value class V {};
ref class G {};
void f(System::Object ^) {}

int main() {
// Native pointer.
   int *pN = nullptr;
// Managed handle.
   G ^pG = nullptr;

实际上,您可以将nullptr用于托管和本机指针。在这种情况下,编译器不会生成错误或警告。代码也能正常运行。只有当您想要明确地在代码中表达“嘿,这是一个本机指针,看,这很重要!”时,您才可以使用__nullptr。因此,这更多地展示了nullptr的含义给其他程序员,而不是关于编译器的代码正确性。


0
如果我理解正确的话,您应该在使用托管指针时使用nullptr,在使用非托管指针时使用__nullptr。然而,由于nullptr可用于托管和非托管指针,个人认为没有理由使用__nullptr

3
但是,如果您使用/clr开关进行编译,编译器如何知道您是否正在使用C++11的nullptr还是C++/CLI的nullptr?它无法知道,这就是为什么在使用/clr开关进行编译时,当您指的是C++11版本时,必须使用__nullptr的原因。 - Michael Price
使用__nullptr的原因是,如果您使用nullptr,则将永远无法启用C++/CLI并利用.NET。这在未来使用旧代码方面是一个巨大的劣势。 - user3690202

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