参考
【C++11新特性】 nullptr关键字
invalid conversion from void* to char*
warning: passing NULL to non-pointer argument of ‘std::thread::thread
nullptr
前言
最近面试遇到的一个问题,平时没怎么注意到,今天研究了下,顺便记录下来.
NULL
1 2 3 4 5 6 7
| #ifndef NULL # if defined __STDC__ && __STDC__ # define NULL ((void *) 0) # else # define NULL 0 # endif #endif
|
nullptr
nullptr是C++11语言标准用来表示空指针的常量值[1],可以指派给任意类型的指针变量[2]。部分编译器将之视为一个关键字,例如Visual Studio[3],部分使用旧标准的C++编译器则未实现需要自行定义[4]或引入额外的头文件[2]。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;} template <class _Tp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator _Tp* () const {return 0;} template <class _Tp, class _Up> _LIBCPP_INLINE_VISIBILITY operator _Tp _Up::* () const {return 0;} friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;} friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;} }; inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);} #define nullptr _VSTD::__get_nullptr_t() _LIBCPP_END_NAMESPACE_STD #else namespace std { typedef decltype(nullptr) nullptr_t; } #endif #endif
|
在c语言中,NULL是void*
,在C++中NULL是0.C++ 11中使用nullptr来表示空指针.
代码
C语言
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <stdio.h> #include <stdlib.h>
void fun1(void* a) { printf("void\n"); }
void fun2(int a) { printf("int\n"); }
void fun3(char* a) { printf("char*\n"); }
int main() { fun3(NULL);
return 0; }
|
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <iostream>
using namespace std;
void fun(void*) { cout << "void" <<endl; }
void fun(int ) { cout << "int" <<endl; }
void fun2(char *) { cout << "char*" << endl; }
int main() { fun(NULL);
return 0; }
|
原理
nullptr是关键字,并且是个prvalue,类型是nullptr_t。nullptr_t的原理是通过operator类型转换函数配合模板来进行任意指针类型的转换:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #include "pch.h" #include <iostream> #include <vector> #include <string> using namespace std;
void func1(int*) { cout << "int*" << endl; }
void func2(char*) { cout << "char*" << endl; }
void func3(void*) { cout << "void*" << endl; }
void func4(string*) { cout << "string*" << endl; }
void func5(vector<int>*) { cout << "vector<int>*\n"; }
class a { public: template <typename _Tp> operator _Tp*() { return 0; } };
int main() { func1(nullptr); func2(nullptr); func3(nullptr); func4(nullptr); func5(nullptr);
a aa; func1(aa); func2(aa); func3(aa); func4(aa); func5(aa); return 0; }
|
int*
char*
void*
string*
vector<int>*
int*
char*
void*
string*
vector<int>*
ending