NULL、nullptr、0剪不断理还乱的关系

NULL 和 0 的歧义

先看下NULL的定义,在stddef.h中(/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/stddef.h)
在这里插入图片描述
在C中,NULL定义为((void*)0)。
在C代码中,一般用NULL表示空指针,即指针的0值。例如:

int *p = NULL;		// 正确
int *p = 0;		// 正确

在C++中,NULL定义为0或者0L。(是0还是0L跟编译器定义的头文件有关)
在C++98代码中,我们也只能用NULL来表示空指针。例如:

#include <iostream>
using namespace std;

class Test
{
public:
	void func()
	{}
};

int main()
{
	int *p = NULL;				// NULL表示普通指针的0值,即空指针
	int *p1 = 0;				// 同上
	void (Test::*p_func)() = NULL;		// NULL表示指向成员函数的指针的0值,函数指针
	void (Test::*p1_func)() = 0;		// 同上
}

// compile cmd
// g++ -g -std=c++11 main.cpp -o main

到现在为止,似乎一切看起来都还挺好的,没什么歧义啊。那我们现在考虑C++函数重载的一种情况,如下:

#include <iostream>
using namespace std;

class Test
{
public:
	void func(int a)
	{
		cout << "call int.." << endl;
	}

	void func(bool b)
	{
		cout << "call bool.." << endl;
	}

	void func(void* c)
	{
		cout << "call void*.." << endl;
	}
};

int main()
{
	Test a;
	a.func(0);	// 调用func(int)
	a.func(NULL);	// 混乱,且编译不通过
}

// compile cmd
// g++ -g -std=c++11 main.cpp -o main

按照我们编码的意思,a.func(NULL)应该会调用func(void*)才对,但是实际情况却是编译不通过,如下:
在这里插入图片描述
为什么呢?
1、a.func(0)这个没问题,是因为0被编译器正确地、严格地认为是int型,所以严格调用了func(int)。
2、但是NULL被认为是0L,这时候没有一个函数能严格匹配,所以0L就要被转换,但是转换成int、bool、void*都可以哪,所以编译器就混乱了,不知道你到底想要调用哪个函数。
解决方案有三种:
case1:再定义一个func(long)函数,就可以使得NULL严格地和long匹配。

void func(long d)
{
	cout << "call long.." << endl;
}

但是,这时候编译还是有warning,如下:
在这里插入图片描述
case2:就是不要让广义整型数和指针重载(这是C++98一个好的编程习惯)。
case3:引入nullptr。

引入nullptr

参考文章和链接

  1. https://www.cnblogs.com/DswCnblog/p/5629073.html
  2. https://www.cnblogs.com/xinxue/p/5415139.html
  3. https://blog.csdn.net/u011304970/article/details/72229013
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章