码迷,mamicode.com
首页 > 编程语言 > 详细

C++11---nullptr

时间:2015-10-25 19:25:14      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

  1.nullprt与NULL

代码:

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

void f(char* c) {
    cout << "f(char*)" << endl;
}
int
main () { f(0); f(\0); // f(NULL); 在我的GCC中编译不过,因为NULL被认为是(void*)0,二义性 // f((void*)0); 二义性 f(nullptr); return 0; }

结果:

技术分享

因为NULL容易出问题,因此出现了nullptr。nullptr是有类型的,并且可以被隐式转化为指针类型。

额外:NULL,0,‘\0‘ 的区别

NULL在 "stdio.h" 中的定义如下:

#ifndef __cplusplus
#define NULL ((void *)0)
#else   /* C++ */
#define NULL 0
#endif  /* C++ */

说明NULL在C中是(void*)0,而在C++中是0.

注意:0对于指针来说是一个特别对待的值,"当常量0处于应该作为指针使用的上下文中时,它就作为空指针使用“

如下程序所示;

int main () {
    void* p;
    p = 0;
    //p = 1; 这里报错了,虽然与0都是int类型
    cout << p << endl;
    return 0;
}

而‘\0‘是所有位都是0的字节,在ASCII码表中所示如下:

技术分享表明‘\0‘的二进制值是0000 0000

有趣的情况:C的字符串是用‘\0‘结尾的,而有的系统(比如Ubuntu14.04)用NULL也能结束(不过这在其他系统不一定能行得通):

int main () {
    char str[3];
    str[0] = a;
    str[1] = b;
    cout << str << endl;
    str[2] = \0;
    cout << str << endl;
    str[2] = 0;
    cout << str << endl;
    return 0;
}

结果:技术分享

这三个都是表现出0,但是你的0不是我的0,如下代码:

int main () {
    cout << "\\0的大小:  " << sizeof(\0‘) << endl;
    cout << "0的大小:   " << sizeof(0) << endl;
    cout << "NULL的大小:" << sizeof(NULL) << endl;
    return 0;
}

结果:技术分享

总:这三者都是零,但是NULL是16进制的0(对于C来说这是(void*)0,是指针),0是10进制的0,‘\0‘是8进制的0

PS:上面NULL可以替代‘\0‘的情况可以理解为,在二进制中,NULL是16个0而‘\0‘是8个0,NULL可以截断最后8位成为‘\0‘。


 

 

  2.nullptr是关键字


 

 

  3.nullptr的类型是nullptr_t

使用nullptr_t需要包含<cstddef>,其定义为typedef decltype(nullptr) nullptr_t;

使用nullptr_t可以定义多个指针空值,而不仅仅是nullptr一个(虽然nullptr已经够用了)

int main () {
    nullptr_t myNull;
    f(myNull);

    return 0;
}

规则:

  • nullptr_t类型数据可以隐式转换成任意一个指针类型。
  • nullptr_t类型数据不能转换为非指针类型,即使reinterpret_cast
  • nullptr_t类型数据不适用于算术运算表达式。
  • nullptr_t类型数据适用于关系算术表达式,但仅能与nullptr_t和指针类型比较。

 

  

  4.nullptr与模板

模板只把nullptr作为一个普通的类型进行推导(并不会视为T* 指针)

template<typename T> void g(T* t) { cout << sizeof(T) << endl;}

template<typename T> void h(T t) { cout << sizeof(T) << endl;}

int main () {
    // g(nullptr); 类型是nullptr_t而不是指针
    g((char*)0);
    g((int*)nullptr);

    h(0);
    h(nullptr);
    h((int*)nullptr);

    return 0;
}

技术分享


 

 

  5.规定sizeof(nullptr_t) == sizeof(void*)

nullptr是一个编译时期的常量,是编译时期的关键字,能被编译器识别。(void*)0需要经过类型转换才能变成其他指针类型。


 

 

  6.nullprt地址

  • 可以打印nullptr_t对象的地址
  • 不能直接打印nullptr的地址
  • 可以打印nullptr的右值引用的地址

代码:

int main () {
    nullptr_t my_null;
    cout << &my_null << endl; //可以打印nullptr_t的地址

    // cout << nullptr << endl; 错误

    const nullptr_t &nullptr_r = nullptr; //可以打印nullptr的右值引用地址
    cout << &nullptr_r << endl;

    return 0;
}

 

参考书籍:《深入理解C++11》

C++11---nullptr

标签:

原文地址:http://www.cnblogs.com/programmer-kaima/p/4458684.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!