nullptr - 指针字面量
nullptr 是C++11引入的指针字面量,用于表示空指针。它解决了传统空指针表示方式(如NULL和0)在类型安全性和重载解析方面的不足。
| Book | Video | Code | X |
|---|---|---|---|
| cppreference / markdown | 视频解读 | 练习代码 |
为什么引入?
- 解决
NULL宏和整数0在重载解析中的歧义问题 - 提供类型安全的空指针表示方式
- 明确区分指针和整数类型
- 支持模板编程中的类型推导
nullptr和NULL有什么区别?
nullptr是C++11引入的关键字,类型为std::nullptr_tNULL是预处理宏,通常定义为整数0或(void*)0nullptr在重载解析中更精确,不会与整数类型混淆
一、基础用法和场景
替代NULL和0
用于指针变量的初始化和赋值,替代传统的
NULL和0
int* ptr1 = nullptr; // 推荐用法
int* ptr2 = NULL; // 传统用法
int* ptr3 = 0; // 不推荐
// 检查指针是否为空
if (ptr1 == nullptr) {
// 处理空指针情况
}
解决重载歧义问题
在函数调用中明确传递空指针,
nulltpr能避免重载歧义问题, 并且避免与整数类型的混淆
void func(int* ptr) {
if (ptr != nullptr) {
*ptr = 42;
}
}
void func(int value) {
// 处理整数参数
}
int main() {
func(nullptr); // 明确调用指针版本
func(0); // 可能调用整数版本,产生歧义
func(NULL); // 可能调用整数版本,产生歧义
}
例如上面的代码中,调用func(NULL)就会报重载歧义错误
main.cpp: In function 'int main()':
main.cpp:16:9: error: call of overloaded 'func(NULL)' is ambiguous
16 | func(NULL); // 可能调用整数版本,产生歧义
| ~~~~^~~~~~
确保模板编程中的类型安全
在模板函数和类中,
nullptr提供更好的类型推导和安全性
// https://en.cppreference.com/w/cpp/language/nullptr.html
template<class T>
constexpr T clone(const T& t) {
return t;
}
void g(int*) {
std::cout << "Function g called\n";
}
int main() {
g(nullptr); // ok
g(NULL); // ok
g(0); // ok
g(clone(nullptr)); // ok
g(clone(NULL)); // ERROR: NULL可能会被推导成非"指针"类型
g(clone(0)); // ERROR: 0会被推导成非"指针"类型
}
当使用函数模板时, NULL和0通过会被推导成非"指针"类型, 而nullptr可以避免这个问题
main.cpp:19:12: error: invalid conversion from 'int' to 'int*' [-fpermissive]
19 | g(clone(0)); // ERROR: 0会被推导成非"指针"类型
| ~~~~~^~~
| |
| int
智能指针和容器
与现代C++特性(如智能指针、STL容器)配合使用
#include <memory>
#include <vector>
int main() {
std::shared_ptr<int> sp1 = nullptr;
std::unique_ptr<int> up1 = nullptr;
std::vector<int*> vec;
vec.push_back(nullptr);
// 检查智能指针是否为空
if (sp1 == nullptr) {
sp1 = std::make_shared<int>(42);
}
}
二、注意事项
类型推导和std::nullptr_t
nullptr的类型是std::nullptr_t,这是一个特殊的类型,可以 隐式 转换为任何指针类型:
#include <cstddef> // 包含std::nullptr_t的定义
void func(int*) {}
void func(double*) {}
void func(std::nullptr_t) {}
int main() {
auto ptr = nullptr; // ptr的类型是std::nullptr_t
func(nullptr); // 调用std::nullptr_t版本
func(ptr); // 调用std::nullptr_t版本
int* intPtr = nullptr;
func(intPtr); // 调用int*版本
}
与布尔类型的隐式转换
nullptr可以隐式转换为bool类型,在条件判断中非常方便:
int* ptr = nullptr;
if (ptr) { // 等价于 if (ptr != nullptr)
// 指针非空
} else {
// 指针为空
}
bool isEmpty = (ptr == nullptr); // true
三、练习代码
练习代码主题
- 0 - nullptr基础用法
- 1 - nullptr的函数重载
- 2 - nullptr在模板编程中的优势
练习代码自动检测命令
d2x checker nullptr