C++11 nullptr实现初始化空指针

实际开发中,避免产生“野指针”最有效的方法,就是在定义指针的同时完成初始化操作,即便该指针的指向尚未明确,也要将其初始化为空指针。

所谓“野指针”,又称“悬挂指针”,指的是没有明确指向的指针。野指针往往指向的是那些不可用的内存区域,这就意味着像操作普通指针那样使用野指针(例如 &p),极可能导致程序发生异常。

C++98/03 标准中,将一个指针初始化为空指针的方式有 2 种:

int *p = 0;
int *p = NULL; //推荐使用

可以看到,我们可以将指针明确指向 0(0x0000 0000)这个内存空间。一方面,明确指针的指向可以避免其成为野指针;另一方面,大多数操作系统都不允许用户对地址为 0 的内存空间执行写操作,若用户在程序中尝试修改其内容,则程序运行会直接报错。

相比第一种方式,我们更习惯将指针初始化为 NULL。值得一提的是,NULL 并不是 C++ 的关键字,它是 C++ 为我们事先定义好的一个宏,并且它的值往往就是字面量 0(#define NULL 0)。

C++ 中将 NULL 定义为字面常量 0,虽然能满足大部分场景的需要,但个别情况下,它会导致程序的运行和我们的预期不符。例如:

#include <iostream>
using namespace std;
void isnull(void *c){
    cout << "void*c" << endl;
}
void isnull(int n){
    cout << "int n" << endl;
}
int main() {
    isnull(0);
    isnull(NULL);
    return 0;
}

程序执行结果为:
int n
int n

对于 isnull(0) 来说,显然它真正调用的是参数为整形的 isnull() 函数;而对于 isnull(NULL),我们期望它实际调用的是参数为 void*c 的 isnull() 函数,但观察程序的执行结果不难看出,并不符合我们的预期。

C++ 98/03 标准中,如果我们想令 isnull(NULL) 实际调用的是 isnull(void* c),就需要对 NULL(或者 0)进行强制类型转换:

isnull( (void*)NULL );
isnull( (void*)0 );

如此,才会成功调用我们预期的函数(读者可自行执行此代码,观察输出结果)。

由于 C++ 98 标准使用期间,NULL 已经得到了广泛的应用,出于兼容性的考虑,C++11 标准并没有对 NULL 的宏定义做任何修改。为了修正 C++ 存在的这一 BUG,C++ 标准委员会最终决定另其炉灶,在 C++11 标准中引入一个新关键字,即 nullptr。

在使用 nullptr 之前,读者需保证自己使用的编译器支持该关键字。以 Visual Studio 和 codeblocks 为例,前者早在 2010 版本就对 C++ 11 标准中的部分特性提供了支持,其中就包括 nullptr;如果使用后者,读者需将其 G++ 编译器版本至少升级至 4.6.1(同时开启 -std=c++0x 编译选项)。

nullptr 是 nullptr_t 类型的右值常量,专用于初始化空类型指针。nullptr_t 是 C++11 新增加的数据类型,可称为“指针空值类型”。也就是说,nullpter 仅是该类型的一个实例对象(已经定义好,可以直接使用),如果需要我们完全定义出多个同 nullptr 完全一样的实例对象。

值得一提的是,nullptr 可以被隐式转换成任意的指针类型。举个例子:

int * a1 = nullptr;
char * a2 = nullptr;
double * a3 = nullptr;

显然,不同类型的指针变量都可以使用 nullptr 来初始化,编译器分别将 nullptr 隐式转换成 int*、char* 以及 double* 指针类型。

另外,通过将指针初始化为 nullptr,可以很好地解决 NULL 遗留的问题,比如:

#include <iostream>
using namespace std;
void isnull(void *c){
    cout << "void*c" << endl;
}
void isnull(int n){
    cout << "int n" << endl;
}
int main() {
    isnull(NULL);
    isnull(nullptr);
    return 0;
}

程序执行结果为:
int n
void*c

借助执行结果不难看出,由于 nullptr 无法隐式转换为整形,而可以隐式匹配指针类型,因此执行结果和我们的预期相符。
总之在 C++11 标准下,相比 NULL 和 0,使用 nullptr 初始化空指针可以令我们编写的程序更加健壮。

到此这篇关于C++11 nullptr实现初始化空指针的文章就介绍到这了,更多相关C++11 nullptr 初始化空指针内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++类的空指针调用成员函数的代码

    类的实例调用成员函数的原理 其实不管是通过对象实例或指针实例调用,其实底层调用的过程都是一样的,都是把当前对象的指针作为一个参数传递给被调用的成员函数.通过下面的相关实例代码进行检验: 实验的C++代码 class Student { private: int age; public: Student() {} Student(int age) : age(age) {} int getAge() { return this->age; } }; int main(int argc, char

  • C++ this指针和空指针的具体使用

    每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码那么问题是:这-块代码是如何区分那个对象调用自己的呢? C++通过提供特殊的对象指针,this指针,解决上述问题.this指针指向被调用的成员函数所属的对象 this指针是隐含每一个非静态成员函数内的-种指针 this指针不需要定义,直接使用即可 this指针的用途: 当形参和成员变量同名时,可用this指针来区分 在类的非静态成员函数中返回对象本身,可使用return this 一.this指针 1 this指针解

  • C++野指针和悬空指针的实现方法

    目录 一.野指针 二.悬空指针 2.1 情况一 2.2 情况二 2.3 情况三 野指针和悬空指针是指针中常见的两个概念,本文结合实例讲解来讲解下. 一.野指针 野指针是指尚未初始化的指针,既不指向合法的内存空间,也没有使用 NULL/nullptr 初始化指针. 来看一个简单例子: #include <iostream> using namespace std; int main() { int *p; // 野指针 int *q = NULL; // 非野指针 p = new int(5);

  • C/C++中利用空指针简化代码,提高效率

    这里的写法,可以避免使用 for 循环,减少栈空间内存的使用和减少运行时的计算开销!#include iostream>   #include string>    using namespace std; void print_char(char* array[]);//函数原形声明 void main(void)      {          char* test[]={"abc","cde","fgh",NULL};//这里添

  • C++11 nullptr实现初始化空指针

    实际开发中,避免产生“野指针”最有效的方法,就是在定义指针的同时完成初始化操作,即便该指针的指向尚未明确,也要将其初始化为空指针. 所谓“野指针”,又称“悬挂指针”,指的是没有明确指向的指针.野指针往往指向的是那些不可用的内存区域,这就意味着像操作普通指针那样使用野指针(例如 &p),极可能导致程序发生异常. C++98/03 标准中,将一个指针初始化为空指针的方式有 2 种: int *p = 0; int *p = NULL; //推荐使用 可以看到,我们可以将指针明确指向 0(0x0000

  • C++11中longlong超长整型和nullptr初始化空指针

    目录 1. C++11:long long 超长整型 2. C++11:nullptr 初始化空指针 本文介绍 C++11 标准中新添加的 long long 超长整型和 nullptr 初始化空指针. 1. C++11:long long 超长整型 C++ 11 标准中,基于整数大小的考虑,共提供了如下表所示的这些数据类型.与此同时,标准中还明确限定了各个数据类型最少占用的位数. 整数类型 等价类型 C++11标准规定占用最少位数 short short int(有符号短整型) 至少 16 位

  • C++深入探究用NULL来初始化空指针是否合适

    目录 1.C++98中的空指针 指针的危险性 2.C++11中的空指针 我们要了解C++11新特性的nullptr,我们很有必要先了解一下C++11之前的程序员是怎么使用空指针的. 1.C++98中的空指针 我们知道,在良好的C/C++编程习惯中,声明一个变量时最好给这个变量赋一个合适的初始值,否则就有可能出现不可预料的错误. 指针的危险性 在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的的数据的内存.为数据提供空间的是一个独立的步骤,忽略这一步无疑是自找麻烦

  • 关于C++11的统一初始化语法示例详解

    前言 本文主要给大家介绍了C++11统一初始化语法的相关内容,关于在当前新标准C++11的语法看来,变量合法的初始化器有如下形式: X a1 {v}; X a2 = {v}; X a3 = v; X a4(v); 其实,上面第一种和第二种初始化方式在本质上没有任何差别,添加=则是一种习惯上的行为.使用花括号进行的列表初始化语法,其实早在C++98时代就有了,只不过历史上他们只是被用来对数组元素进行初始化操作,以及初始化自定义POD类型的数据(简单理解就是可以memcpy复制对象的类型).比如:

  • C++11中列表初始化机制的概念与实例详解

    目录 概述 实现机制详解 POD类型的列表初始化 含有构造函数的类的列表初始化(C++11) 列表初始化用于函数返回值 引入std::initializer_list 代码验证 应用 列表初始化防止类型收窄 总结 概述 定义:列表初始化是C++11引入的新标准,目的是统一初始化方式 C++11以前只能使用列表初始化来初始化内置类型数组和POD类型对象,C++11中列表初始化可以用于初始化任何类型对象 POD(plain old data)类型:仅由内置类型变量构成且不含指针的类,简单来说是可以直

  • C++11中初始化列表initializer lists的使用方法

    C++11引入了初始化列表来初始化变量和对象.自定义类型,如果想用初始化列表就要包含initializer_list头文件. C++11将使用大括号的初始化(列表初始化)作为一种通用初始化方式,可用于所有类型.初始化列表不会进行隐式转换. C++11提供的新类型,定义在<initializer_list>头文件中. template< class T > class initializer_list; 先说它的用处吧,然后再详细介绍一下. 首先有了initializer_list之

  • C++11新特性之列表初始化的具体使用

    目录 统一的初始化方法 列表初始化的一些使用细节 初始化列表 1.任何长度的初始化列表 2.std::initialzer-list的使用细节 列表初始化防止类型收窄 在我们实际编程中,我们经常会碰到变量初始化的问题,对于不同的变量初始化的手段多种多样,比如说对于一个数组我们可以使用 int arr[] = {1,2,3}的方式初始化,又比如对于一个简单的结构体: struct A { int x; int y; }a={1,2}; 这些不同的初始化方法都有各自的适用范围和作用,且对于类来说不能

  • C++11系列学习之列表初始化

    目录 前言: 旧标准初始化方式 C++11标准初始化方式 初始化列表技术细节 总结 前言: 由于旧标准初始化方式太过繁杂,限制偏多,因此在新标准中统一了初始化方式,为了让初始化具有确定的效果,于是提出了列表初始化概念. 旧标准初始化方式 普通数组初始化: int i_arr[3] = {1, 2, 3} POD类型初始化(即plain old data类型,可以直接使用memcpy复制的对象): struct A { int x; struct B { int i; int j; } b; }

  • C++中各种初始化方式示例详解

    前言 本文主要给大家介绍了关于C++初始化方式的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. C++小实验测试:下面程序中main函数里a.a和b.b的输出值是多少? #include <iostream> struct foo { foo() = default; int a; }; struct bar { bar(); int b; }; bar::bar() = default; int main() { foo a{}; bar b{}; std::co

  • C++11 并发指南之多线程初探

    C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧,和大家共勉. 相信 Linux 程序员都用过 Pthread, 但有了 C++11 的 std::thread 以后,你可以在语言层面编写多线程程序了,直接的好处就是多线程程序的可移植性得到了很大的提高,所以作为一名 C++ 程序员,熟悉 C++11 的多线程编程方式还是很有益处的. 如果你对 C++11

随机推荐