前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 中的 nullptr 到底是什么

C++ 中的 nullptr 到底是什么

作者头像
ClearSeve
发布2022-02-10 19:07:00
2.6K0
发布2022-02-10 19:07:00
举报
文章被收录于专栏:ClearSeveClearSeve

问题

C++11 中的 nullptr 到底是什么?.

回答

在 C 语言中,我们使用 NULL 表示空指针,它实际上是一个宏,具体被定义为,

代码语言:javascript
复制
/* C 语言程序 */
#define NULL ((void*)0)
#define NULL 0 /* 两者皆可 */

注:因为在C 语言中,是允许 void 指针隐式转换为其它类型指针的,所以 #define NULL ((void*)0) 这样的定义不会有问题。

C++ 语言出现后,为了保持对 C 语言的兼容,保留了 NULL,但对 NULL 的定义变得更为严格,

代码语言:javascript
复制
/* C++ 语言程序 */
#ifdef __cplusplus
    #define NULL 0
#else
    #define NULL ((void*)0)
#endif

NULL 被定义为 0,而不是 ((void*)0),因为在 C++ 语言中,void 指针是不可以隐式转换为其它类型指针的,必须显示转换,

代码语言:javascript
复制
/* C++ 语言程序 */
#define NULL ((void*)0) /* 如果在 C++ 语言中这么定义的话 */

int* a = NULL; /* 隐式转换,错误 */
int* a = (int*)NULL; /* 显示转换,正确,但很麻烦,所以 NULL 都会被定义为 0 */

在 C++98 之前(包括 C++98),在对 NULL 的使用上,都一直存在一个问题,假设有下面的代码,

代码语言:javascript
复制
/* C++ 语言程序 */
void func(int i);
void func(char* p);

func(NULL); /* 该调用哪个?*/

NULL 其实就是等于 0,对于上面的两个函数,它都是符合的,如此,就会出现语义二义性的错误。

为了解决上述重载函数所带来的问题,C++11 的 nullptr 应运而生。nullptr 实质上是一个常量,实现代码大致如下,

代码语言:javascript
复制
/* C++ 语言程序 */
const /* 常量 */
class
{
public:
    template<class T>
    operator T*() const /* 向任意类型的非成员指针转换 */
    {
        return 0;
    }

    template<class C, class T>
    operator T C::*() const /* 向任意类型的成员指针转换 */
    {
        return 0;
    }

private:
    void operator&() const /* 不可取地址 */
    {
    }
} nullptr = {};

nullptr 只是一个常量,这就意味着我们可以在程序中随意定义一个与其名称相同的标识符,但因为 nullptr 在实际编程中的应用实在太广泛,因此 C++ 编译器一般都会把 nullptr 定为关键字,避免程序员的滥用。

当然,C++11 发布后,并没有因为 nullptr 的出现,而摒弃 NULL,主要是为了兼容旧版程序。

最后,总结一下,

  1. 在 C 语言编程中,请使用 NULL 此时的 NULL,要么是 ((void*)0),要么是 0,对于 C 语言而言,都无所谓。
  2. 在 C++ 语言编程中,请使用 nullptr 既为了避免以后出现 bug,也为了养成一个良好的编程习惯。

参考文献:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022年1月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 回答
  • 参考文献:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档