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 <iostream>
#include <cstddef> // for std::nullptr_t

///
// reference: http://en.cppreference.com/w/cpp/language/nullptr
template<class F, class A>
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;
}

GitHubhttps://github.com/fengbingchun/Messy_Test

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值