C++11中nullptr的使用

在C语言中,NULL实际上是一个void* 的指针,然后把void* 指针赋值给其它类型的指针的时候,会隐式转换成相应的类型。而如果用一个C++编译器来编译的时候是要出错的,因为C++是强类型的,void* 是不能隐式转换成其它指针类型的。在C++中为了解决空指针的问题,在C++中引入0来表示空指针。NULL无类型,它是一个宏。nullptr是有类型的,类型是std::nullptr_t。

推荐:纯C语言用NULL;C++用0;如果编译器支持nullptr,使用nullptr。

The keyword nullptr denotes the pointer literal. It is a prvalue(pure rvalue) of type std::nullptr_t. There exist implicit conversions from nullptr to null pointer value of any pointer type and any pointer to member type. Similar conversions exist for any null pointer constant, which includes values of type std::nullptr_t as well as the macro NULL.

Both true and false are keywords and as literals they have a type ( bool ). nullptr is a pointer literal of type std::nullptr_t, and it's a prvalue (you cannot take the address of it using &).

A null pointer constant with the nullptr value has the following characteristics:

(1)、It can be converted to any pointer or pointer-to-member type.

(2)、It cannot be implicitly converted to any other type, except for the bool type.

(3)、It cannot be used in an arithmetic expression.

(4)、It can be compared with the integer 0.

(5)、It can be used in relational expressions to compare with pointers or data of the std::nullptr_t type.

It should be noted that in C++11 it is still acceptable to assign the value 0 or NULL to a pointer.

在VS2013中,NULL的定义是在stdio.h文件中,如下:

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else  /* __cplusplus */
#define NULL    ((void *)0)
#endif  /* __cplusplus */
#endif  /* NULL */

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "nullptr.hpp"

#include 
#include  // for std::nullptr_t

///////////////////////////////////////////
// reference: http://en.cppreference.com/w/cpp/language/nullptr
template
void Fwd(F f, A a)
{
	f(a);
}

void g(int* i)
{
	std::cout << "Function g called\n";
}

int test_nullptr1()
{
	g(NULL);           // Fine
	g(0);              // Fine

	Fwd(g, nullptr);   // Fine
	// Fwd(g, NULL);  // ERROR: No function g(int) // error C2664: “void (int *)”: 无法将参数 1 从“int”转换为“int *”

	int length1 = sizeof(NULL); // x64, length1 = 4
	int length2 = sizeof(nullptr); // x64, length2 = 8

	return 0;
}

///////////////////////////////////////////
// reference: https://msdn.microsoft.com/zh-cn/library/4ex65770.aspx
class MyClass {
public:
	int i;
};

int test_nullptr2()
{
	MyClass * pMyClass = nullptr;
	if (pMyClass == nullptr)
		std::cout << "pMyClass == nullptr" << std::endl; // pMyClass == nullptr

	if (pMyClass == 0)
		std::cout << "pMyClass == 0" << std::endl; // pMyClass == 0

	pMyClass = 0;
	if (pMyClass == nullptr)
		std::cout << "pMyClass == nullptr" << std::endl; // pMyClass == nullptr

	if (pMyClass == 0)
		std::cout << "pMyClass == 0" << std::endl; // pMyClass == 0

	return 0;
}

/////////////////////////////////////////////////////
void f(int *)
{
	std::cout << "f(int *)" << std::endl;;
}

void f(int &)
{
	std::cout << "f(int &)" << std::endl;
}

int test_nullptr3()
{
	f(nullptr); // f(int *)
	// try one of the following lines instead
	f((int *) nullptr); // f(int *)
	f(0); // f(int *)
	f(NULL); // f(int *)
	//f((int &) nullptr); // error C2101: 常量上的“&”

	return 0;
}

//////////////////////////////////////////////
// reference: http://www.cprogramming.com/c++11/c++11-nullptr-strongly-typed-enum-class.html
void func(int n)
{
	std::cout << "func (int n)" << std::endl;
}

void func(char *s)
{
	std::cout << "func (char *s)" << std::endl;
}

int test_nullptr4()
{
	func(0); // func (int n)
	func(NULL); // func (int n)
	func(nullptr); // func (char *s)

	return 0;
}

//////////////////////////////////////////////////////////
// reference: http://www.learncpp.com/cpp-tutorial/6-7a-null-pointers/
void doSomething(int *ptr)
{
	if (ptr)
		std::cout << "You passed in " << *ptr << '\n';
	else
		std::cout << "You passed in a null pointer\n";
}

void doSomething_(std::nullptr_t ptr)
{
	std::cout << "in doSomething_()\n";
}

int test_nullptr5()
{
	int* a = NULL; // ok
	//int* b = (void*)0; // error C2440: “初始化”: 无法从“void *”转换为“int *”
	int* c = 0; // ok

	// the argument is definitely a null pointer (not an integer)
	doSomething(nullptr); // You passed in a null pointer
	doSomething(0); // You passed in a null pointer
	doSomething(NULL); // You passed in a null pointer

	// call doSomething_ with an argument of type std::nullptr_t
	doSomething_(nullptr); // in doSomething_()

	return 0;
}

GitHub:https://github.com/fengbingchun/Messy_Test

你可能感兴趣的:(C/C++/C++11)