从0到1:C++ 语法之 nullptr
Hello 大家好!今天我们又见面了!!!我依然是那个刚刚入门编程不久,但是对于编程有着极度热情的一个菜鸟,还是非常希望大家和我进行学习方面的交流,一起努力、一起进步~~~
今天我要和大家分享的是 C++ 中的一个语法 nullptr。
说到 C++ 中的 nullptr,就不得不从 C 语言中的 NULL 说起。
一:NULL
NULL 的含义是指针没有指向任何有效的内存位置。(一块儿不太可能被用到的地址被 NULL 指向)。
NULL 实际上是一个宏,在传统的 C 头文件(stddef.h)中,可以看到如下代码:
#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif
不难看出,C++ 中NULL可能被定义为子面常量0,或者 C 中被定义为无类型指针(void*)的常量。不论采用何种定义,在使用空值的指针时,都不可避免地会遇到一些麻烦。C++ 设计之初的目的就是解决 C 语言某些方面的缺陷或者不足。
请看下面的场景:
#include <iostream>
using namespace std;void f(int x)
{cout << "f(int x)" << endl;
}void f(int* ptr)
{cout << "f(int* ptr)" << endl;
}int main()
{f(0);f(NULL);return 0;
}
我们本想通过 f(NULL) 调用指针版本的 f(int*)函数,但是由于 C++中 NULL 被定义成了0,调用了 f(int x),发生了错配,因此与程序的初衷相悖。
为了解决上面的情况,我们就不得不这样调用:
f((int*)NULL);
通过强制类型转化来满足我们的初衷,这样用起来就显得很奇怪,很麻烦。
如果我们一不小心写错成下面的样子,就会编译报错:
// 编译报错:error C2665:“f”:两个重载中没有一个可以转换所有的参数类型
f((void*)NULL);
没有合适的重载函数与其匹配~~。
二:nullptr
C++ 11中引入了 nullptr, nullptr 是一个特殊的关键字,nullptr 是一种特殊类型的字面量。它可以转换成任意其他类型的指针类型。使用 nullptr 定义空指针可以避免类型转换的问题,因为 nullptr 只能被隐式地转换为指针类型,而不能被转换为整数类型。
引入了 nullptr 用起来相对 C 语言就方便了很多。
#include <iostream>
using namespace std;void f(int x)
{cout << "f(int x)" << endl;
}void f(int* ptr)
{cout << "f(int* ptr)" << endl;
}int main()
{f(nullptr);return 0;
}
此时 nullptr 就会去调用指针版本的 f 函数。
但是,下面这个场景就会报错,虽然几个函数构成重载,但是编译器不知道要去调用哪一个重载函数。
#include <iostream>
using namespace std;void f(int x)
{cout << "f(int x)" << endl;
}void f(int* ptr)
{cout << "f(int* ptr)" << endl;
}void f(char* ptr)
{cout << "f(char* ptr)" << endl;
}void f(void* ptr)
{cout << "f(void* ptr)" << endl;
}int main()
{f(nullptr);return 0;
}
nullptr 仍然可以被强转~~
#include <iostream>
using namespace std;void f(int x)
{cout << "f(int x)" << endl;
}void f(int* ptr)
{cout << "f(int* ptr)" << endl;
}void f(char* ptr)
{cout << "f(char* ptr)" << endl;
}void f(void* ptr)
{cout << "f(void* ptr)" << endl;
}int main()
{f((char*)nullptr);return 0;
}
这样的话就不会报错了~~
总结:
1.在函数重载中,NULL 和 0 会造成歧义,以后尽量就用 nullptr 代表空指针,而不是 NULL。
2.关键字 nullptr 提高了程序的类型安全性和可读性,与宏定义 NULL 相比,具有更强的可靠性和拓展性。
好的,今天的分享就到达这里,希望对大家有所帮助。