系列文章目录
C++11新特性使用详解-持续更新
https://blog.csdn.net/xiaofeizai1116/category_12498334.html
文章目录
- 系列文章目录
- 一、简介
- 二、引入nullptr原因
- 1. 消除歧义
- 2. 兼容性问题
- 3. 类型安全
- 三、使用场景
- 1. 初始化指针变量
- 2. 判断指针是否为空
- 3. 释放内存后置为空
- 四、总结
一、简介
C++11引入了nullptr关键字,它是一种空指针类型,用于表示空指针。
二、引入nullptr原因
C++11之前空指针一般用`NULL宏或者0值表示,为什么还有引入nullptr呢?
1. 消除歧义
NULL宏在不同的编译器环境中可能代表不同的值,容易造成对空指针的理解混乱;另外把0赋给指针,也容易给人造成把整数常量赋给指针的误解。使用nullptr从语言层面解决了上述问题,提高了代码的可读性。
Note
NULL本质上是0,在内存中表示不存在或没有指向任何对象的指针。如果一个指针被初始化为NULL,意味着它目前不指向任何对象或数据。
2. 兼容性问题
不同平台对NULL的定义不同,可能导致移植问题。相比之下,因为nullptr是语言层面的关键字,不会存在平台依赖性问题,从而提高代码的可移植性。
3. 类型安全
nullptr是一个类型安全的空指针,它明确地表示一个空指针,不能转换成任何除void*以外的其他类型。避免了使用NULL时可能出现的类型转换问题。
Note
NULL是一个宏,不是关键字,所以它不会被编译器检查类型。如果将其用于需要指针类型的地方,编译器会将其视为0,而不是一个指针类型。
/*
下面这段代码会运行时会崩溃,原因如下
NULL是一个宏,通常被定义为0或((void*)0),表示一个空指针。当我们将一个指针变量赋值为NULL时,它表示这个指针变量不指向任何有效的内存地址。
在解引用一个指针时,我们需要将指针所指向的内存地址中的值读取出来。在代码int x = *p1中,表示读取p1所指向的内存地址中的值。由于p1是一个int类型的指针,编译器期望p1指向一个整数类型的内存地址。但是,由于NULL是一个void*类型的值,它不是一个整数类型的值,当试图将一个void类型的值赋给一个int类型的变量时,因为类型不匹配,编译器会报错。
*/
int* p1 = NULL;
int x = *p1;
/*
相比之下,使用nullptr可以避免类型不匹配的问题。
nullptr是一个类型安全的空指针,它明确地表示一个空指针。
编译器会检查使用nullptr的上下文,确保它被正确地用于指针类型。在这段代码中,p2被初始化为nullptr,表示它是一个空指针。
由于p2被声明为int*类型,编译器期望p2指向一个整数。然而,由于p2是空的,不能解引用它来获取一个整数值。编译器会报错,避免了类型转换问题。
*/
int* p2 = nullptr;
int x = *p2; // 编译器会报错,因为p是一个空指针
三、使用场景
1. 初始化指针变量
用nullptr声明一个空指针变量
int* p = nullptr; // 初始化一个整型指针变量p,值为空指针
在需要指针类型的地方,编译器会根据上下文自动将nullptr转换为正确的指针类型
/*
在这个例子中,我们调用func函数时传递了一个空指针作为参数。编译器会自动将nullptr转换为整数类型的指针,并传递给func函数。
func函数在接收到空指针后,就可以避免对无效的内存地址进行操作,从而避免了潜在的错误。
*/
void func(int* p) { // ...
} int main() { func(nullptr); // 使用nullptr表示不传递任何有效的指针 return 0;
}
2. 判断指针是否为空
int* p = getPointFunc();
if (p != nullptr) { // 如果p不为空指针,则执行这里的代码
}
3. 释放内存后置为空
int* p = new int; // 动态分配内存
// 使用p指向的内存
delete p; // 释放内存
p = nullptr; // 明确地将p设置为空指针
四、总结
总的来说,nullptr是以一种更安全、更清晰的方式来处理空指针。只要正确理解和合理使用,它就能够帮助我们编写出质量更高、更容易维护的代码。