nullptr 源代码
// -*- C++ -*-
//===--------------------------- __nullptr --------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_NULLPTR
#define _LIBCPP_NULLPTR
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_NULLPTR
_LIBCPP_BEGIN_NAMESPACE_STD
struct _LIBCPP_TEMPLATE_VIS nullptr_t
{
void* __lx;
struct __nat {int __for_bool_;};
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
template
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
operator _Tp* () const {return 0;}
template
_LIBCPP_ALWAYS_INLINE
operator _Tp _Up::* () const {return 0;}
friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
};
inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
#define nullptr _VSTD::__get_nullptr_t()
_LIBCPP_END_NAMESPACE_STD
#else // _LIBCPP_HAS_NO_NULLPTR
namespace std
{
typedef decltype(nullptr) nullptr_t;
}
#endif // _LIBCPP_HAS_NO_NULLPTR
#endif // _LIBCPP_NULLPTR
// 源代码内容详细分析
//
// main.m
// test_cpp_nullptr_01
//
// Created by jeffasd on 2017/10/1.
// Copyright © 2017年 jeffasd. All rights reserved.
//
#include
#include
using namespace std;
class Person {
public:
// Person p;
// // 隐式的转换
// cout << p << endl;
// 当实现以下两个类的转换函数时会出现编译错误编译器编译到上面的代码不知道该使用哪一个转换函数
operator int () {
return 0;
}
#if 0
operator int * () {
return 0;
}
#endif
// Person p;
// //显式的转换
// cout << (int)p << endl;
// cout << (int *)p << endl;
// cout << (char)p << endl;
};
class Student : public Person {};
struct _LIBCPP_TEMPLATE_VIS nullptr_test
{
void * __lx;
struct __nat {int __for_bool_;};
// 调用方式 nullptr_test();
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_test() : __lx(0) {
int a = 3;
a = 4;
}
// 'int Person::*'表示Person类内int *类型的成员类型', (抛去类限定符可以理解为:int *) 调用方式 nullptr_test((int(Person::*))0);
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_test(int Person::*) : __lx(0)
{
int a = 3;
a = 4;
}
// 'int Person::**'表示Person类内int **类型的成员类型', (抛去类限定符可以理解为:int **) 调用方式 nullptr_test((int(Person::**))0);
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_test(int Person::**) : __lx(0)
{
int a = 3;
a = 4;
}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_test(int) : __lx(0)
{
int a = 3;
a = 4;
}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_test(int *) : __lx(0)
{
int a = 3;
a = 4;
}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_test(Person *) : __lx(0)
{
int a = 3;
a = 4;
}
// 'int __nat::*'表示__nat类内int *类型的成员类型', (抛去类限定符可以理解为:int *) 调用方式 nullptr_test((int(nullptr_test::__nat::*))0);
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_test(int __nat::*) : __lx(0)
{
int a = 3;
a = 4;
}
// operator作为类的转换函数
// 定义了一个将类型转化为int的转换函数
// 重载了将nullptr_test类型转化为int的函数
// operator int ()
// {
// return 0;
// }
// // operator作为类的转换函数
// // 定义了一个将类型转化为int *的转换函数
// // 重载了将nullptr_test类型转化为int *的函数
// operator int * () {
// return 0;
// }
// 重载了将nullptr_test类型转化为'int __nat::*'的函数
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {
int a = 3;
a = 4;
return 0;
}
// 重载了将nullptr_test类型转化为'_Tp*'的函数 - 由于重载了两个将nullptr_test类型转为指针的函数 编译器无法隐式处理类型转换函数因此
// nullptr_test nullTestInstanc;
// cout << nullTestInstanc << endl; // 隐式的转换 将nullptr_test类型转为(指针)类型 - 此表达式会报错
// operator _Tp* () const {return 0;} // 转换为非成员变量指针、非成员函数指针的普通指针
template
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
operator _Tp* () const {
int a = 3;
a = 4;
return 0;
}
// operator _Tp _Up::* () const {return 0;} // 转换为成员变量指针或成员函数指针
template
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
operator _Tp _Up::* () const {
int a = 3;
a = 4;
return 0;
}
friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_test, nullptr_test) {
return true;
}
friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_test, nullptr_test) {
return false;
}
};
inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_test __get_nullptr_t_test() {
nullptr_test();
nullptr_test((int(Person::*))0);
nullptr_test((int(Person::**))0);
nullptr_test(0);
nullptr_test((int *)0);
nullptr_test((Person *)0);
nullptr_test((int(nullptr_test::__nat::*))0);
return nullptr_test(0);
}
#define nullptrTest __get_nullptr_t_test()
namespace jeffasd
{
typedef decltype(nullptrTest) nullptr_test;
}
int main (int argc, const char * argv[]) {
void *testJeffasd = nullptrTest;
Person p;
cout << p << endl;// 隐式的转换 将Person类型转为int类型
// 由于nullptr_test类重载了两个将nullptr_test类型转为指针的函数 编译器无法隐式处理类型转换函数 - 要想将nullptr_test类型转为指针类型只能显示转换类型。
nullptr_test nullTestInstanc;
printf("----\n");
cout << (int *)nullTestInstanc << endl; // 显式的转换 将nullptr_test类型转为(int *)类型
cout << (Person *)nullTestInstanc << endl; // 显式的转换 将nullptr_test类型转为(Person *)类型
printf("----\n");
cout << (Student *)nullTestInstanc << endl; // 显式的转换 将nullptr_test类型转为(Student *)类型
printf("----\n");
printf("----\n");
cout << (int Person::*)nullTestInstanc << endl; // 显示的转换 将nullptr_test类型转为Person类int *类型的成员变量
cout << (Person Person::*)nullTestInstanc << endl; // 显示的转换 将nullptr_test类型转为Person类Person *类型的成员变量
cout << (void (Person::*)(void))nullTestInstanc << endl;
// 成员变量指针类型 - 成员函数指针类型
// ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template operator _Tp _Up::* () const
int Student::* memberVariablePointer = nullptr; // 成员函数指针
// ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template operator _Tp _Up::* () const
void (Student::* memberFunctionPointer)(int, char) = nullptr;
nullptr_t nulljeffasd;
cout << (int *)nulljeffasd << endl;
return 0;
}
// 参考内容:
// https://blog.csdn.net/afei198409/article/details/17398675?utm_source=blogxgwz3
// https://blog.csdn.net/sunxu2016/article/details/77074683