一 具體實現(xiàn)
代碼(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修飾誉帅,意味著里面的變量是不能更改的卡乾。
同時類里面有兩個公有函數(shù)如下:
template<class T>
operator T*() const;
template<class C, class T>
operator T C::*() const
其中template<class T>表示模板善延,意味著声功,T可以使用戶自定義的類型叛复。既然是空指針,那么很多種類型的指針都可以指向它家厌,所以使用了模板播玖。使用了operator關鍵字,operator表示重載饭于,重載有很多種蜀踏,在這里此函數(shù)為一個隱式轉換函數(shù)。const表示此函數(shù)不修改類的成員變量掰吕。如果對這方面不是很清楚可以參考
1.c++模板詳解 2.C++ operator兩種用法這兩篇博客果覆。
在函數(shù)里面只做了一件事也就是返回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
第二個函數(shù)和上面的一樣只是模板不同
template<class C, class T>
operator T C::*() const
{
cout << "C::T* is called" << endl;
return 0;
}
目的是為了給類的成員指針變量賦予空指針钳榨。所以你可以根據你自己的需求寫出各種模板參數(shù)。
private中void operator&() const;
即為將&符號禁用纽门。因為空指針沒有引用這一說薛耻。
3.檢驗測試
在main函數(shù)中分別定義了一下變量
int *p = mynullptr;
int A::*c = mynullptr;
int *
的指針p并賦予空指針,和以及對類A 的成員指針賦予空指針赏陵。
要把mynullptr賦給左邊的值饼齿,由于右邊mynullptr的類型與左邊不同,所以此時要進行隱式類型轉化瘟滨,如何轉化呢?還記得我們在類中寫的那兩個函數(shù)嗎候醒,他們就是隱式轉化的函數(shù)。根據左邊的類型去匹配模板杂瘸,第一個當然與T*
匹配,所以調用第一個隱式轉化函數(shù)伙菊,于是結果打印了T*is called
同樣的第二個應該調用第二個隱式轉換函數(shù)败玉,打印了C::T* is called
。我們知道空指針的地址為0地址镜硕,所以第一個打印了00000000(32位系統(tǒng)指針占4個字節(jié)运翼,所以是8個0)。第二個由于是成員指針兴枯,代表的是偏移量血淌,所以打印了0。