C++中NULL与nullptr的区别对比

前言

在编写C程序的时候只看到过NULL,而在C++的编程中,我们可以看到NULL和nullptr两种关键字,其实nullptr是C++11版本中新加入的,它的出现是为了解决NULL表示空指针在C++中具有二义性的问题,为了弄明白这个问题,我查找了一些资料,总结如下。

一、C程序中的NULL

在C语言中,NULL通常被定义为:#define NULL ((void *)0)

所以说NULL实际上是一个空指针,如果在C语言中写入以下代码,编译是没有问题的,因为在C语言中把空指针赋给int和char指针的时候,发生了隐式类型转换,把void指针转换成了相应类型的指针。

int  *pi = NULL;
char *pc = NULL;

二、C++程序中的NULL

但是问题来了,以上代码如果使用C++编译器来编译则是会出错的,因为C++是强类型语言,void*是不能隐式转换成其他类型的指针的,所以实际上编译器提供的头文件做了相应的处理:

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif

可见,在C++中,NULL实际上是0.因为C++中不能把void*类型的指针隐式转换成其他类型的指针,所以为了结果空指针的表示问题,C++引入了0来表示空指针,这样就有了上述代码中的NULL宏定义。

但是实际上,用NULL代替0表示空指针在函数重载时会出现问题,程序执行的结果会与我们的想法不同,举例如下:

#include <iostream>
using namespace std;

void func(void* i)
{
 cout << "func1" << endl;
}

void func(int i)
{
 cout << "func2" << endl;
}

void main(int argc,char* argv[])
{
 func(NULL);
 func(nullptr);
 getchar();
}

在这段代码中,我们对函数func进行可重载,参数分别是void*类型和int类型,但是运行结果却与我们使用NULL的初衷是相违背的,因为我们本来是想用NULL来代替空指针,但是在将NULL输入到函数中时,它却选择了int形参这个函数版本,所以是有问题的,这就是用NULL代替空指针在C++程序中的二义性。

三、C++中的nullptr

为解决NULL代指空指针存在的二义性问题,在C++11版本(2011年发布)中特意引入了nullptr这一新的关键字来代指空指针,从上面的例子中我们可以看到,使用nullptr作为实参,确实选择了正确的以void*作为形参的函数版本。

总结:

NULL在C++中就是0,这是因为在C++中void* 类型是不允许隐式转换成其他类型的,所以之前C++中用0来代表空指针,但是在重载整形的情况下,会出现上述的问题。所以,C++11加入了nullptr,可以保证在任何情况下都代表空指针,而不会出现上述的情况,因此,建议以后还是都用nullptr替代NULL吧,而NULL就当做0使用。

其他:在没有C++ 11的nullptr的时候,我们怎么解决避免这个问题呢?

const class nullptr_t
{
public:
    template<class T>
    inline operator T*() const
        { return 0; }

    template<class C, class T>
    inline operator T C::*() const
        { return 0; }

private:
void operator&() const;
} nullptr = {};

到此这篇关于C++中NULL与nullptr区别对比的文章就介绍到这了,更多相关C++ NULL与nullptr区别内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++中NULL与nullptr的区别对比

    前言 在编写C程序的时候只看到过NULL,而在C++的编程中,我们可以看到NULL和nullptr两种关键字,其实nullptr是C++11版本中新加入的,它的出现是为了解决NULL表示空指针在C++中具有二义性的问题,为了弄明白这个问题,我查找了一些资料,总结如下. 一.C程序中的NULL 在C语言中,NULL通常被定义为:#define NULL ((void *)0) 所以说NULL实际上是一个空指针,如果在C语言中写入以下代码,编译是没有问题的,因为在C语言中把空指针赋给int和char

  • django数据模型中null和blank的区别说明

    虽然本人使用django也有几年的时间,但是还是对django中数据模型的null和blank有点分不清楚,我想很多人也和我一样的困惑,现在将全面彻底的讲解下两个的区别. 一.null的使用 1.默认是False的,如果设置为True的时候,django将会映射到数据表指定是否为空 2.如果这个字段设置为False的时候,如果没给这个字段传递任何值的时候,django也会使用一个空字符串('')存储进去 3.如果这个字段设置为True的时候,django会产生两种空值的情形(null和空字符串)

  • JavaScript中Null与Undefined的区别解析

    在JavaScript中存在这样两种原始类型:Null与Undefined.这两种类型常常会使JavaScript的开发人员产生疑惑,在什么时候是Null,什么时候又是Undefined? Undefined类型只有一个值,即undefined.当声明的变量还未被初始化时,变量的默认值为undefined. Null类型也只有一个值,即null.null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象. 复制代码 代码如下: var oValue;  alert(oValue ==

  • java 中接口和抽象类的区别与对比

    java 中接口和抽象类的区别与对比 接口和抽象类的概念不一样. 接口是对动作的抽象,抽象类是对根源的抽象. 抽象类表示的是,这个对象是什么.接口表示的是,这个对象能做什么.比如,男人,女人,这两个类(如果是类的话--),他们的抽象类是人.说明,他们都是人. 人可以吃东西,狗也可以吃东西,你可以把"吃东西"定义成一个接口,然后让这些类去实现它. 所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口.走路接口). 第一点:接

  • js中不同的height, top的区别对比

    每次看到js中的 clientHeight(clientTop), offsetHeight(offsetTop),scrollHeight(scrollTop)就头大,根本分不清这几种的区别,然而碰到这些已经不 值一两次了,然后每次都要查看一下各自的区别,才能决定使用哪个. 本篇主要以chrome为准,可能各个浏览器之间还是有一些区别,但很多自己还未真正遇到过,还不是很清楚,等以后碰到了类似的兼容性问题,再记录到这里,这次就chrome浏览器中各个属性的区别做个记录,以方便以后的查看 一 cl

  • Python中的None与 NULL(即空字符)的区别详解

    1.首先要了解Python的对象的概念: Python中,万物皆对象,所有的操作都是针对对象的,那什么是对象,5是一个int对象,'oblong'是一个str对象,异常也是一个对象,抽象一点是,人,猫,够也是一个对象 那对于一个对象,它就有包括两方面的特征:  属性:去描述它的特征  方法: 它所具有的行为 所以,对象=属性+方法 (其实方法也是一种属性,一种区别于数据属性的可调用属性 把具有相同属性和方法的对象就可以归为一类,即Classl.类就好比是一张蓝图,使用一个类可以创建多个对象实例

  • Java中Exception和Error的区别详解

    世界上存在永远不会出错的程序吗?也许这只会出现在程序员的梦中.随着编程语言和软件的诞生,异常情况就如影随形地纠缠着我们,只有正确的处理好意外情况,才能保证程序的可靠性. java语言在设计之初就提供了相对完善的异常处理机制,这也是java得以大行其道的原因之一,因为这种机制大大降低了编写和维护可靠程序的门槛.如今,异常处理机制已经成为现代编程语言的标配. 今天我要问你的问题是,请对比Exception和Error,另外,运行时异常与一般异常有什么区别? 典型回答 Exception和Error都

  • 详谈java中int和Integer的区别及自动装箱和自动拆箱

    目录 int和Integer的区别及自动装箱和自动拆箱 Integer和int的对比,如下图所示: 自动装箱和自动拆箱: Integer的自动拆装箱的陷阱(整型数-128到127的值比较问题) 1.先看下面的例子: 2.以下是Integer.valueof()的源代码: int和Integer的区别及自动装箱和自动拆箱 1.Integer是int的包装类,int则是java的一种基本数据类型. 2.Integer变量必须实例化后才能使用,int则不需要. 3.Integer实际是对象的引用,当n

  • Java中int和Integer的区别

    目录 1.基本数据类型 2.包装类及其作用 2.1包装类的作用 3.int 和 Integer 的区别 4.总结 重要说明:本篇为博主<面试题精选-基础篇>系列中的一篇,查看系列面试文章请关注我. Gitee 开源地址:gitee.com/mydb/interv- nJava 是一种强数据类型的语言,因此所有的属性必须有一个数据类型.就像麦德龙超市一样,想要进去购物,先要有一个会员卡才行(刷卡入内).​ PS:Java 10 有了局部变量类型推导,可以使用 var 来替代某个具体的数据类型,但

  • C#与C++枚举的区别对比和使用案例

    C++与C#中枚举的区别 一.C++ 枚举类型中的每个元素,可以直接使用,不必通过类型.元素的方式调用 没有++操作 #include <iostream> using namespace std; enum week{Monday,Thuesday}; int main() { week day; day = Monday; day = Thuesday; //day = 4; 报错 类型转化出错 //day++; 出错,没有++ 操作 cout << day <<

随机推荐