一 具体实现

代码(c++)

const class nullptr_t
{
public:
template<class T>
inline operator T*() const
{ return 0; } template<class C, class T>
inline operator T C::*() const
{ return 0; } private:
void operator&() const;
} nullptr = {};

来自维基百科

二 解析
  1. 在vs2013写了如下代码,作为解析演示。
//nullptr.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
const class mynullptr_t
{
public:
template<class T>
inline operator T*() const
{
cout << "T* is called" << endl;
return 0;
}
template<class C, class T>
inline operator T C::*() const
{
cout << "T C::* is called" << endl;
return 0;
} private:
void operator&() const; } mynullptr = {}; class A{
public:
int *a;
}; int main(){ int *p = mynullptr;
int A::*a = mynullptr;
cout << p << endl;
cout << a << endl; }

结果输出

T* is called
T C::* is called
00000000
0

2.解释

首先申明了一个类(为了避免冲突我使用了mynullptr_t)使用了const修饰,意味着里面的变量是不能更改的。

同时类里面有两个公有函数如下:

template<class T>
operator T*() const;
template<class C, class T>
operator T C::*() const

其中template表示模板,意味着,T可以使用户自定义的类型。既然是空指针,那么很多种类型的指针都可以指向它,所以使用了模板。使用了operator关键字,operator表示重载,重载有很多种,在这里此函数为一个隐式转换函数。const表示此函数不修改类的成员变量。如果对这方面不是很清楚可以参考

1.c++模板详解 2.C++ operator两种用法这两篇博客。

在函数里面只做了一件事也就是返回0,为什么返回0呢?因为在对指针赋值时如果指针=0,也即意味着这个指针为一个空指针。原因是因为在<stdio.h>头文件下有以下定义:

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

将NULL 定义为了0;

不信的话可以试一试

int *p = 0;
cout << p << endl;

输出:00000000

第二个函数和上面的一样只是模板不同

template<class C, class T>
operator T C::*() const
{
cout << "C::T* is called" << endl;
return 0;
}

目的是为了给类的成员指针变量赋予空指针。所以你可以根据你自己的需求写出各种模板参数。

private中void operator&() const;即为将&符号禁用。因为空指针没有引用这一说。

3.检验测试

在main函数中分别定义了一下变量

int *p = mynullptr;
int A::*c = mynullptr;

int *的指针p并赋予空指针,和以及对类A 的成员指针赋予空指针。

要把mynullptr赋给左边的值,由于右边mynullptr的类型与左边不同,所以此时要进行隐式类型转化,如何转化呢?还记得我们在类中写的那两个函数吗,他们就是隐式转化的函数。根据左边的类型去匹配模板,第一个当然与T*匹配,所以调用第一个隐式转化函数,于是结果打印了T*is called同样的第二个应该调用第二个隐式转换函数,打印了C::T* is called。我们知道空指针的地址为0地址,所以第一个打印了00000000(32位系统指针占4个字节,所以是8个0)。第二个由于是成员指针,代表的是偏移量,所以打印了0。

自己实现一个nullptr的更多相关文章

  1. nullptr和NULL 区别

    注:本文内容摘自网络,准确性有待验证,现阶段仅供学习参考.尊重作品作者成果,原文链接 :http://www.2cto.com/kf/201302/190008.html 1.为什要有nullptr ...

  2. 聊一聊c++中指针为空的三种写法 ----->NULL, 0, nullptr

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

  3. C++11新特性之四——nullptr

    1. 引入nullptr的原因 引入nullptr的原因,这个要从NULL说起.对于C和C++程序员来说,一定不会对NULL感到陌生.但是C和C++中的NULL却不等价.NULL表示指针不指向任何对象 ...

  4. (转)null和NULL和nullptr和””区别

    突然想到这个有趣的问题:C语言和C++对大小写是敏感的,也就是说null和NULL是区别对待的.NULL代表空地址,null只是一个符号.便来深究,看了很多资料,总结如下: 其实null和NULL都是 ...

  5. C++的那些事:函数全解析

    一.函数的结构 函数在C++中可能出现在三种地方,一是函数的定义,它包括了如上图的结构:二是函数的声明,它与函数的定义相比,没有了函数体部分:三则是函数的调用.当然,不同的函数定义可以还会稍有不同,比 ...

  6. 你好,C++(33)对象生死两茫茫 6.2.3 一个对象的生与死:构造函数和析构函数

    6.2.2  使用类创建对象 完成某个类的声明并且定义其成员函数之后,这个类就可以使用了.一个定义完成的类就相当于一种新的数据类型,我们可以用它来定义变量,也就是创建这个类所描述的对象,表示现实世界中 ...

  7. [转载] C++11新特性

    C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...

  8. stl_各容器的总结

    一.stl容器总结: 1.以下的操作是在一千万的数据下操作.copy 都是在足够的空间下进行的copy, 测量方式: std::clock_t start = std::clock(); //待测代码 ...

  9. c++智能指针和二叉树(1): 图解层序遍历和逐层打印二叉树

    二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不胜数. 然而大多数文章都是讲解的前序/中序/后序遍历,有关逐层打印元素的文章并不多,已有文章的讲解也较为晦涩读起来不得要领.本文将用形象的 ...

随机推荐

  1. 两篇文章带你走入.NET Core 世界:Kestrel+Nginx+Supervisor 部署上云服务器(二)

    背景: 上一篇:两篇文章带你走入.NET Core 世界:CentOS+Kestrel+Ngnix 虚拟机先走一遍(一) 已经交待了背景,这篇就省下背景了,这是第二篇文章了,看完就木有下篇了. 直接进 ...

  2. Java 10 var关键字详解和示例教程

    在本文中,我将通过示例介绍新的Java SE 10特性——“var”类型.你将学习如何在代码中正确使用它,以及在什么情况下不能使用它. 介绍 Java 10引入了一个闪亮的新功能:局部变量类型推断.对 ...

  3. php批量修改文件名称

    <?php//利用PHP目录和文件函数遍历用户给出目录的所有的文件和文件夹,修改文件名称function fRename($dirname){ if(!is_dir($dirname)){ ec ...

  4. [Swift-2019力扣杯春季决赛]4. 有效子数组的数目

    给定一个整数数组 A,返回满足下面条件的 非空.连续 子数组的数目: 子数组中,最左侧的元素不大于其他元素. 示例 1: 输入:[1,4,2,5,3] 输出:11 解释:有 11 个有效子数组,分别是 ...

  5. 试试自行封装AJAX和jQuery中的ajax封装的基本使用

    封装的套路: 1.写一个相对比较完善的用例2.写一个空函数,没有形参,将刚刚的用例直接作为函数的函数体3.根据使用过程中的需求抽象函数 代码记录如下: <script> function ...

  6. Fiddler原理~知多少?

    首先我们学习Fidder这个工具,我们就应该去了解它的基本东西,比如这个单词的意思.Fiddler叫:小提琴.骗子的意思. 那么它是干什么的呢? Fiddler是一个http协议调试代理工具,它能够记 ...

  7. 从零开始学习PYTHON3讲义(十三)记事本的升级版:网络记事本

    <从零开始PYTHON3>第十三讲 网络编程的火热和重要性这里就不多说了,我们直接来看看Python在互联网编程方面的表现. Python有很多网络编程的第三方扩展包,这里推荐一个我认为最 ...

  8. RecyclerViewItemTouchHelperDemo【使用ItemTouchHelper进行拖拽排序功能】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 记录使用ItemTouchHelper对Recyclerview进行拖拽排序功能的实现. 效果图 代码分析 ItemTouchHel ...

  9. Java~关于开发工具和包包

    大叔也学java了,距离上学时接触的java已经有10多年了,看着确实有些陌生了,不过还是希望学学,感受一下这个当今最牛X的语言!开发工具IDE对于一个语言来说是很必要的,就是Csharp使用vs一样 ...

  10. Mybatis+mysql批量插入性能分析测试

    前言 今天在网上看到一篇文章(后文中的文章指的就是它) https://www.jianshu.com/p/cce617be9f9e 发现了一种有关于mybatis批量插入的新方法,而且看了文章发现我 ...