看到同事用了一下nullptr.不是很了解这方面东东,找个帖子学习学习 http://www.cppblog.com/airtrack/archive/2012/09/16/190828.aspx

NULL:

NULL是c语言的东西,定义处: #define NULL ((void *)0)

我们可以写  int* i = NULL, foo_t* pObj = NULL.

NULL实际上是一个void *的指针,然后吧void *指针赋值给int *和foo_t *的时候,会隐式转换成相应的类型。而如果换做一个C++编译器来编译的话是要出错的,因为C++是强类型的,void *是不能隐式转换成其他指针类型的,所以通常情况下,编译器提供的头文件会这样定义NULL:

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif

C++ 的0

因为C++中不能将void *类型的指针隐式转换成其他指针类型,而又为了解决空指针的问题,所以C++中引入0来表示空指针,这样就有了类似上面的代码来定义NULL。实际上C++的书都会推荐说C++中更习惯使用0来表示空指针而不是NULL,尽管NULL在C++编译器下就是0。为什么C++的书都推荐使用0而不是NULL来表示空指针呢?我们看一个例子:

 //foo.h
void bar(type1 a, type2* b); //foo.h中的bar函数在a.cpp和b.cpp中都被调用了. //a.cpp
.....
bar(a,b);
..... //b.cpp
.....
bar(a, );
..... //现在,上面的代码都能编译运行.但是突然某天我们要功能扩展,需要对bar函数扩展,我们使用了重载 foo.h变成如下:
void bar(sometype1 a, sometype2 *b);
void bar(sometype1 a, int i); //这个时候就危险了.因为a.cpp和b.cpp中的调用代码这个时候就不能按照期望的运行了。但是我们很快就会发现b.cpp中的0是整数,也就是在overload resolution的时候,我们知道它调用的是void bar(sometype1 a, int i)这个重载函数,于是我们可以做出如下修改让代码按照期望运行: bar(a, static_cast<type2 *>()); //我知道,如果我们一开始就有bar的这两个重载函数的话,我们会在一开始就想办法避免这个问题(不使用重载)或者我们写出正确的调用代码,然而后面的这个重载函数或许是我们几个月或者很长一段时间后加上的话,那我们出错的可能性就会加大了不少。貌似我们现在说道的这些跟C++通常使用0来表示空指针没什么关系,好吧,假设我们的调用代码是这样的:
//foo.h
void bar(type1 a, type2 *b); //a.cpp
......
bar(a, b);
......
//b.cpp
.....
bar(a,NULL);
..... //当bar的重载函数在后面加上来了之后,我们会发现出错了,但是出错的时候,我们找到b.cpp中的调用代码也很快可能忽略过去了,因为我们用的是NULL空指针啊,应该是调用的void bar(type1 a, type2 *b)这个重载函数啊。实际上NULL在C++中就是0,写NULL这个反而会让你没那么警觉,因为NULL不够“明显”,而这里如果是使用0来表示空指针,那就会够“明显”,因为0是空指针,它更是一个整形常量。 在C++中,使用0来做为空指针会比使用NULL来做空指针会让你更加警觉。

C++ 11的nullptr

 //虽然上面我们说明了0比NULL可以让我们更加警觉,但是我们并没有避免这个问题。这个时候C++ 11的nullptr就很好的解决了这个问题,我们在C++ 11中使用nullptr来表示空指针,这样最早的代码是这样的

 //foo.h

 void bar(type1 a, type2* b);
-------------------------------------------
7 | //a.cpp | //b.cpp |
| .... | ....... |
| bar(a,b); | bar(a, nullptr);|
| ....... | ........ |
---------------------------------------------
在我们后来把bar的重载加上了之后,代码是这样: //foo.h
void bar(type1 a, type2 *b);
void bar(type1 a, int i); //a.cpp //b.cpp
.... .....
bar(a,b); bar(a,nullptr);
.... ...... //这时候,我们的代码还是能够如期的正确运行. //在没有C++11的nullptr的时候,我们应该怎么解决避免这个问题呢?我们可以自己实现一个nullptr const
class nullptr_t
{
public:
template<class T>
inline operator T*() const
{ return ; } template<class C, class T>
inline operator T C::*() const
{ return ; } private:
void operator&() const;
} nullptr = {};


和小伙伴都惊了个呆了啊...上面自己实现的nullptr_t类完全看不懂的样子,得一句一句的分析分析啊...

 const                       //参见下文解释1
class nullptr_t
{
public:
template<class T>
inline operator T* () const //参见下文解释2
{
return ;
} template<class C, class T>
inline operator T C::*() const //参见下文解释3
{
return ;
} private:
void operator& () const; //参见下文解释4 }nullptr = {}; //参见下文解释5

解释1 : 在类前面的const是什么!!

 //类前面的const 是修饰 类后面定义的对象的.

 const
class A
{
public:
int i;
}a,b; //等价于
class A
{
public:
int i;
}; const A a;
const A b;

解释2 : 这个模板函数是什么?

 template <class T>
inline operator T* () const
{
return ;
} //上面的模板函数是在重载 类型转换运算符 (跟 重载 operator = 一样都是在重载运算符).
//我们知道重载运算符是要带返回值的,例如下面的类重载等号 是要返回A&的
class A
{
public:
A& operater = (const A& Obj)
{
i = Obj.i;
j = Obj.j;
}
private:
int i;
int j;
};
//但是呢.重载 类型转换运算符比较特殊. (c++ primer,可以查“用户自定义类型转换符”找到讲解) 规定为:转换函数不能写返回类型(规定的),返回的类型就是 operator 后面跟的类型
所以:
inline operator T* () const
---------------------------------------------
这是一个类型转换函数,把A类型(这里是return 0 的 0的类型)转换成 T*的类型
inline 表示内联函数,写不写无所谓。
operator 代表重载某种操作 operator T* () 就是重载类型转换
const 表示 成员变量是只读,不能改。 return _data; // 有返回值,返回值类型是operator后面的T*类型。

解释3 : 这个模板函数又是什么???

解释4:  只写函数声明,不写函数实现真的可以么??

事实证明是可以的,只有没人调用这个函数是可以编译运行成功的..但是如果有人调用的话编译就会报错了.

解释5: 类对象 = {} 中的 ={}是什么??

= {} 是c++11的语法,代表给这个变量初始化

聊一聊c++中指针为空的三种写法 ----->NULL, 0, nullptr的更多相关文章

  1. Android平台中实现对XML的三种解析方式

    本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...

  2. Java中获取键盘输入值的三种方法

    Java中获取键盘输入值的三种方法     Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值 ...

  3. MVC3中,在control里面三种Html代码输出形式

    MVC3中,在control里面三种Html代码输出形式:ViewData["msg"] = "<br /> Title <br />" ...

  4. jquery 在页面中三种写法

    jQuery 分 2 个系列版本 1.x 与 2.x,主要的区别在于 2.x 不再兼容 IE6.7.8浏览器,这样做的目的是为了兼容移动端开发.由于减少了一些代码,使得该版本比 jQuery 1.x ...

  5. Shell脚本中字符串判空:使用-z 字符串长度为0时,为真,-n字符串长度不为0,为真。这两个都不靠谱【转】

    最近发现使用  -z   和  -n  来判断字符串判空,或不空时,很不靠谱. 使用下面的方法最可靠: if [ "x${value}" == "x" ]    ...

  6. 在Tomcat中部署web项目的三种方式

    搬瓦工搭建SS教程 SSR免费节点:http://www.xiaokeli.me 在这里介绍在Tomcat中部署web项目的三种方式: 1.部署解包的webapp目录 2.打包的war文件 3.Man ...

  7. 【转载】取得系统中网卡MAC地址的三种方法

    From:http://blog.csdn.net/zhangting1987/article/details/2732135 网卡地址这个概念有点混淆不清.因为实际上有两个地址,mac地址和物理地址 ...

  8. Tomcat中部署web应用的三种方式

    Tomcat中部署web应用的三种方式(静态部署)       第一种,针对war或解压后的war,最为常用的是直接操作webapp目录,将完整的war包或者web应用直接放到webapp目录下.使用 ...

  9. spring中创建bean对象的三种方式以及作用范围

    时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有 ...

随机推荐

  1. 探索AutoLayout的本质和解决一些问题

    最近频繁使用AutoLayout,记录下自己的一些发现和问题的解决(不是教程) 1.简介 Auto Layout 是苹果在 iOS 6中新引入的布局方式,旨在解决不同尺寸屏幕的适配问题. 屏幕适配工作 ...

  2. Yii 通过composer 安装的方法

    Yii2框架可以通过两种方式 安装 : 第一种方法: Yii2有两个模板 一个是基础模板,一个是高级模板,基础可能简单点吧.........,现在直接从   https://github.com/yi ...

  3. PHP文件的上传下载

    一.文件的上传 1.客户端设置: (1).在 标签中将enctype和method两个属性指明相应的值. Enctype="multipart/form-data"; Method ...

  4. ubuntu给手机建wifi

    声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载,可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站 ...

  5. sql执行计划解析案例(二)

    sql执行计划解析案例(二)   今天是2013-10-09,本来以前自己在专注oracle sga中buffer cache 以及shared pool知识点的研究.但是在研究cache buffe ...

  6. 如何在客户端配置ODBC来访问远程DB2 for Windows服务器

    如何在客户端配置ODBC来访问远程DB2 for Windows服务器                                  马根峰                    (广东联合电子服 ...

  7. iOS上文本绘制的几种方法

    文本绘制在开发客户端程序中是一个比较常用的功能,可分为采用控件和直接绘制两种方式. 采用控件的方式比较简便,添加一个比如UILabel对象,然后设置相关属性就好了.但这种方式局限性也比较大. 直接绘制 ...

  8. hadoop错误org.apache.hadoop.yarn.exceptions.YarnException Unauthorized request to start container

    错误: 14/04/29 02:45:07 INFO mapreduce.Job: Job job_1398704073313_0021 failed with state FAILED due to ...

  9. 使用passenger在Centos7部署Puma+Nginx+Ruby on Rails

    安装ruby环境 RVM(ruby版本管理工具)安装 gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A170311 ...

  10. day-7

    /* 倒数7天了 某一天 某一刻 某次呼吸 我们终将再分离 而我的 自传里 曾经有你 没有遗憾的诗句 诗句里 充满感激 (小仙女博客抄来的233) 是啊 就快要结束了 曲终人散 上午被错误数据卡了一小 ...