问题描述
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 calledT C::* is called000000000
解释:首先申明了一个类(为了避免冲突我使用了mynullptr_t)使用了const修饰,意味着里面的变量是不能更改的。同时类里面有两个公有函数
template<class T>operator T*() const;template<class C, class T>operator T C::*() const
其中template<class T>表示模板,意味着,T可以使用户自定义的类型。既然是空指针,那么很多种类型的指针都可以指向它,所以使用了模板。使用了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;即为将&符号禁用。在main函数中分别定义了一下变量
int *p = mynullptr;int A::*c = mynullptr;
int *的指针p并赋予空指针,和以及对类A 的成员指针赋予空指针。要把mynullptr赋给左边的值,所以说此时要进行隐式类型转化,如何转化呢。还记得我们在类中写的那两个函数吗,他们就是隐式转化的函数。根据左边的类型去匹配模板,第一个当然与T*匹配,所以调用第一个隐式转化函数,于是结果打印了T* is called。同样的第二个应该调用第二个隐式转换函数,打印了C::T* is called。我们知道空指针的地址为0地址,所以第一个打印了00000000(32位系统指针占4个字节,所以是8个0)。第二个由于是成员指针,代表的是偏移量,由于是空指针所以是0。