一 具体实现

代码(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. Pytorch系列教程-使用Seq2Seq网络和注意力机制进行机器翻译

    前言 本系列教程为pytorch官网文档翻译.本文对应官网地址:https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutor ...

  2. javascript 实现数据结构 - 栈

    栈是一种遵从后进先出(LIFO)原则的有序集合.新添加的或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底.在栈里,新元素都靠近栈顶,旧元素都接近栈底.栈就好像是一个底部密封的盒子,我们往里面 ...

  3. ASP.NET Core 实战:将 .NET Core 2.0 项目升级到 .NET Core 2.1

    一.前言  最近一两个星期,加班,然后回去后弄自己的博客,把自己的电脑从 Windows 10 改到 Ubuntu 18.10 又弄回 Windows 10,原本计划的学习 Vue 中生命周期的相关知 ...

  4. centos修改主机名的正确方法

    1 centos6下修改hostname [root@centos6 ~]$ hostname # 查看当前的hostnmae centos6.magedu.com [root@centos6 ~]$ ...

  5. .NET Core和Swagger 生成 Api 文档

    测试/生产环境的BUG 这里更新一下在本地调试正常,在INT/PROD上抛错,错误信息为: */**/*.xml(Swagger json file) 文件找不到,在startup 里builder ...

  6. Spring Cloud Alibaba基础教程:Sentinel使用Apollo存储规则

    上一篇我们介绍了如何通过Nacos的配置功能来存储限流规则.Apollo是国内用户非常多的配置中心,所以,今天我们继续说说Spring Cloud Alibaba Sentinel中如何将流控规则存储 ...

  7. 每周分享五个 PyCharm 使用技巧(二)

    这是 「PyCharm 技巧分享」系列的第二篇分享.由于上一篇文章得到了大家的一些赞同,所以今天又来给大家推荐一些我平时自己有用的小技巧,大家择需所取即可. 先声明下,并不保证对所有的人都是有帮助的, ...

  8. asp.net mvc 简单项目框架的搭建过程(一)对Bll层和Dal层进行充分解耦

    学习asp.net 已经有近三个月的时间了,在asp.net mvc上花的时间最多,但个人真是有些菜,不得不说,asp.net mvc的水真的还是蛮深的.目前在公司实习,也见过公司几个项目的代码了.对 ...

  9. js对象数组(JSON) 根据某个共同字段 分组

    首先判断 var arr = [ {"id":"1001","name":"值1","value": ...

  10. 【开源分享】2018CRM C# 源码(基于小黄豆CRMv2.0.925.3版本功能更新)

    分享出来的初衷,我分享一下最近我在小黄豆CRM2.0版本(小黄豆CRM+v2.0.925.3)上加的功能,如果有类似需求的,可以把功能代码发你,节约你的开发时间.(这是在小黄豆开源免费CRM①群231 ...