自己实现一个nullptr
一 具体实现
代码(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 = {};
来自维基百科
二 解析
- 在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的更多相关文章
- nullptr和NULL 区别
注:本文内容摘自网络,准确性有待验证,现阶段仅供学习参考.尊重作品作者成果,原文链接 :http://www.2cto.com/kf/201302/190008.html 1.为什要有nullptr ...
- 聊一聊c++中指针为空的三种写法 ----->NULL, 0, nullptr
看到同事用了一下nullptr.不是很了解这方面东东,找个帖子学习学习 http://www.cppblog.com/airtrack/archive/2012/09/16/190828.aspx N ...
- C++11新特性之四——nullptr
1. 引入nullptr的原因 引入nullptr的原因,这个要从NULL说起.对于C和C++程序员来说,一定不会对NULL感到陌生.但是C和C++中的NULL却不等价.NULL表示指针不指向任何对象 ...
- (转)null和NULL和nullptr和””区别
突然想到这个有趣的问题:C语言和C++对大小写是敏感的,也就是说null和NULL是区别对待的.NULL代表空地址,null只是一个符号.便来深究,看了很多资料,总结如下: 其实null和NULL都是 ...
- C++的那些事:函数全解析
一.函数的结构 函数在C++中可能出现在三种地方,一是函数的定义,它包括了如上图的结构:二是函数的声明,它与函数的定义相比,没有了函数体部分:三则是函数的调用.当然,不同的函数定义可以还会稍有不同,比 ...
- 你好,C++(33)对象生死两茫茫 6.2.3 一个对象的生与死:构造函数和析构函数
6.2.2 使用类创建对象 完成某个类的声明并且定义其成员函数之后,这个类就可以使用了.一个定义完成的类就相当于一种新的数据类型,我们可以用它来定义变量,也就是创建这个类所描述的对象,表示现实世界中 ...
- [转载] C++11新特性
C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...
- stl_各容器的总结
一.stl容器总结: 1.以下的操作是在一千万的数据下操作.copy 都是在足够的空间下进行的copy, 测量方式: std::clock_t start = std::clock(); //待测代码 ...
- c++智能指针和二叉树(1): 图解层序遍历和逐层打印二叉树
二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不胜数. 然而大多数文章都是讲解的前序/中序/后序遍历,有关逐层打印元素的文章并不多,已有文章的讲解也较为晦涩读起来不得要领.本文将用形象的 ...
随机推荐
- Pytorch系列教程-使用Seq2Seq网络和注意力机制进行机器翻译
前言 本系列教程为pytorch官网文档翻译.本文对应官网地址:https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutor ...
- javascript 实现数据结构 - 栈
栈是一种遵从后进先出(LIFO)原则的有序集合.新添加的或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底.在栈里,新元素都靠近栈顶,旧元素都接近栈底.栈就好像是一个底部密封的盒子,我们往里面 ...
- ASP.NET Core 实战:将 .NET Core 2.0 项目升级到 .NET Core 2.1
一.前言 最近一两个星期,加班,然后回去后弄自己的博客,把自己的电脑从 Windows 10 改到 Ubuntu 18.10 又弄回 Windows 10,原本计划的学习 Vue 中生命周期的相关知 ...
- centos修改主机名的正确方法
1 centos6下修改hostname [root@centos6 ~]$ hostname # 查看当前的hostnmae centos6.magedu.com [root@centos6 ~]$ ...
- .NET Core和Swagger 生成 Api 文档
测试/生产环境的BUG 这里更新一下在本地调试正常,在INT/PROD上抛错,错误信息为: */**/*.xml(Swagger json file) 文件找不到,在startup 里builder ...
- Spring Cloud Alibaba基础教程:Sentinel使用Apollo存储规则
上一篇我们介绍了如何通过Nacos的配置功能来存储限流规则.Apollo是国内用户非常多的配置中心,所以,今天我们继续说说Spring Cloud Alibaba Sentinel中如何将流控规则存储 ...
- 每周分享五个 PyCharm 使用技巧(二)
这是 「PyCharm 技巧分享」系列的第二篇分享.由于上一篇文章得到了大家的一些赞同,所以今天又来给大家推荐一些我平时自己有用的小技巧,大家择需所取即可. 先声明下,并不保证对所有的人都是有帮助的, ...
- asp.net mvc 简单项目框架的搭建过程(一)对Bll层和Dal层进行充分解耦
学习asp.net 已经有近三个月的时间了,在asp.net mvc上花的时间最多,但个人真是有些菜,不得不说,asp.net mvc的水真的还是蛮深的.目前在公司实习,也见过公司几个项目的代码了.对 ...
- js对象数组(JSON) 根据某个共同字段 分组
首先判断 var arr = [ {"id":"1001","name":"值1","value": ...
- 【开源分享】2018CRM C# 源码(基于小黄豆CRMv2.0.925.3版本功能更新)
分享出来的初衷,我分享一下最近我在小黄豆CRM2.0版本(小黄豆CRM+v2.0.925.3)上加的功能,如果有类似需求的,可以把功能代码发你,节约你的开发时间.(这是在小黄豆开源免费CRM①群231 ...