转载于:http://blog.csdn.net/soaliap/article/details/7663865
从1972年C语言刚刚诞生以来,常数0就扮演着整数(int)0和空指针( null pointer )两种角色。为了避免理解上的二义性,C语言通常使用NULL宏来表示空指针,NULL宏通常被定义为(void *)0或0, 而C++仅仅采用0来表示空指针,这样存在一个问题:比如对于重载函数 fun(char *) 和 fun(int) 的调用来说,若直接用NULL作为参数调用fun(NULL),我们可能认为NULL作为空指针的表示,应该调用 fun(char *) 函数,然而NULL实际上的值为0,就会调用 fun(int) 。 nullptr 关键字正是为了解决这一问题而产生的。
nullptr 能够转换成任何指针类型(包括成员函数指针和成员变量指针)和bool类型(这是为了兼容普通指针都能使用 if(ptr) 判断是否为空指针的形式),但是不能被转换为整数0。
下面分析并测试了libcxx中 nullptr_t 的实现,对于转换为bool型别的调用还有些困惑。
// test.cpp
#include <iostream>
using std::cout;
using std::endl;
namespace myname {
struct nullptr_t
{
void * _;
struct __nat {int __for_bool_;};
nullptr_t(int __nat::*) {} // 构造函数,参数可以是0(空指针),或者&__nat::__for_bool_
operator int __nat::*() const {return 0;} // 不理解为什么转换为bool型时会调用此转换函数
// operator bool() const {return 0; /* or return false; */} // 为什么不这样实现?
template <class _Tp>
operator _Tp* () const {return 0;} // 转换为非成员变量指针、非成员函数指针的普通指针
template <class _Tp, class _Up>
operator _Tp _Up::* () const {return 0;} // 转换为成员变量指针或成员函数指针
friend bool operator==(nullptr_t, nullptr_t) {return true;}
friend bool operator!=(nullptr_t, nullptr_t) {return false;}
friend bool operator<(nullptr_t, nullptr_t) {return false;}
friend bool operator<=(nullptr_t, nullptr_t) {return true;}
friend bool operator>(nullptr_t, nullptr_t) {return false;}
friend bool operator>=(nullptr_t, nullptr_t) {return true;}
};
struct Test {};
}
using namespace myname;
inline nullptr_t __get_nullptr_t() {return nullptr_t(0);}
#define nullptr __get_nullptr_t()
int main(int argc, char *argv[])
{
char *pch = nullptr; // ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template <class _Tp> nullptr_t::operator _Tp* () const
int *pint = nullptr; // ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template <class _Tp> nullptr_t::operator _Tp* () const
bool b = nullptr; // ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => nullptr_t::operator int __nat::*() const
//int n = nullptr; // error: cannot convert 'myname::nullptr_t' to 'int' in initialization
int Test::*p = nullptr; // ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template <class _Tp, class _Up> operator _Tp _Up::* () const
void (Test::*pfn)(int, char) = nullptr; // ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template <class _Tp, class _Up> operator _Tp _Up::* () const
return 0;
}
参考: 维基百科 C++11 ( http://en.wikipedia.org/wiki/C%2B%2B11 )