C++ 2011: nullptr
来源:互联网 发布:string数组中删除元素 编辑:程序博客网 时间:2024/04/29 12:51
C++ used to lack a special value to indicate a null pointer. It used 0 for this purpose, something that was inherited from C. This led to some problems, which we'll show in this article. The new standard introduces a new reserved word nullptr, to designate a constant rvalue that represents a null pointer.
NULL is ZERO
In C++ a null pointer is:
A null pointer constant is an integral constant expression (expr.const) rvalue of integer type that evaluates to zero.
This was inherited from C where
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.
Since there is no keyword in the language for a null pointer, both C and C++ compiler provide an implementation-dependent macro called NULL. In VC++ and GCC this is defined as
:
#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
Integer 0 implicitly converts to any pointer type. The use of 0 as a special value for null pointers can lead to some issues, the most important being with calling overloaded functions. Let's look at these two overloaded functions:
void foo(int) {cout << "int" << endl;}void foo(char*) {cout << "pointer" << endl;}
The q uestion is, which of the two would be called for foo(0)? The answer is the first one. To be able to call the second one with a null pointer an explicit cast to char* should be made, i.e. foo((char*)0). On the other hand, the following line of code is valid and calls that constructor of std::basic_string that takes a char*:
string str(false);
The nullptr Reserved Word
The new standard introduces a reserved word called nullptr to represent a null pointer. It designates a constant rvalue of type decltype(nullptr):
typedef decltype(nullptr) nullptr_t;
The nullptr_t type:
- Is a typedef for decltype(nullptr)
- Is a POD type convertible to a pointer type and pointer-to-member type
- Objects of this type can be copied and thrown
- It is possible to take the address of a nullptr_t object
- reinterpret_cast to/from a nullptr_t object is possible
- nullptr_t matches a T* and a T::* partial specialization
The nullptr:
- Is a literal (just like 0 or false)
- The address of nullptr cannot be taken
- Can be used with sizeof, typeid and ternary conditional operator
It is important to note that the standard library macro NULL is not (re-)defined to nullptr; the result of that would be a lot of broken code.
It is possible to use 0 (NULL) and nullptr interchangeably (which is important for compatibility), like in the following examples:
int* p1 = 0;int* p2 = nullptr;if(p1 == 0) {}if(p2 == 0) {}if(p1 == nullptr) {}if(p2 == nullptr) {}if(p1 == p2) {}if(p2) {}
It is not possible however to assign nullptr to an integer value, nor to compare nullptr to an integer.
int n1 = 0; // okint n2 = nullptr; // errorif(n1 == nullptr) {} // errorif(n2 == nullptr) {} // errorif(nullprt) {} // error
Also, because nullptr is an rvalue constant, it's not possible to assign it a value.
nullptr = 0;
For the overloading problem presented in the previous paragraph, use of nullptr would call the overload that takes a char*.
void foo(int) {cout << "int" << endl;}void foo(char*) {cout << "pointer" << endl;}foo(0); // calls foo(int)foo(nullptr); // calls foo(char*)
nullptr can be used with the ternary conditional operator:
int* p1 = ...;int* p2 = true ? p1 : nullptr;
However, the following cases are erroneous:
int* p2 = true ? 0 : nullptr; // incompatible typesint n1 = true ? nullptr : nullptr; // nullptr cannot be converted to intint n2 = true ? 0 : nullptr; // incompatible types
Given these two template functions:
template<typename T>void fooptr(T* t);template<typename T>void foo(T t);
The following cases are possible:
fooptr((int*)0); // type T deduced to intfooptr((int*)nullptr); // type T deduced to intfoo(0); // type T deduced to intfoo((int*)0); // type T deduced to int*foo(nullptr); // type T deduced to nullptr_tfoo((int*)nullptr); // type T deduced to int*
while these are errors:
fooptr(0); // error, type T cannot be deducedfooptr(nullptr); // error, type T cannot be deduced
Conclusions
The new C++ standard defines a reserved word nullptr (representing a constant rvalue of typenullptr_t) that designates a null pointer. For compatibility reasons 0 can still be used as null pointer, and 0 and nullptr can be used interchangeably; also for compatibility reasons, macro NULL will not be redefined to nullptr.
About the Author
- NULL、0、nullptr (C++)
- Modern C++(五)nullptr关键字
- C++ 2011: nullptr
- nullptr
- nullptr
- nullptr
- nullptr
- nullptr
- C ++中的NULL与nullptr的区别
- C/C++之NULL、0、nullptr详解
- C/C++中的NULL与nullptr
- createWithSpriteFrameName nullptr
- C++ nullptr
- nullptr介绍
- C++ nullptr
- nullptr 简介
- nullptr详解
- nullptr关键字
- WPF中播放声音媒体文件
- 模板模式和策略模式的区别
- ISAPI
- Linux系统启动过程剖析过程
- js变量未定义问题
- C++ 2011: nullptr
- java上传附件到本地服务器,调用linux命令然后再传输到远程服务器
- VC中Radio控件的用法
- c++面试题
- Object-C学习
- 多学多得呀,关于函数的可变参数问题
- SSL协议与数字证书原理
- Hadoop job配置文件的生成
- Vim+cscope+ctags+tags阅读源代码