[转]为什么要引入nullptr?
来源:https://cloud.tencent.com/developer/ask/69685
C++11介绍nullptr,它被称为Null指针常数及其提高类型安全性和解决不明确的情况与现有实现相关的空指针常量不同NUL。能够理解nullptr我们首先要明白什么是NULL与此相关的问题是什么。
何谓NULL一点儿没错
Pre C++11NULL用于表示没有值的指针或不指向任何有效内容的指针。与流行的观念相反NULL不是C++中的关键字。它是标准库标头中定义的标识符。总之,你不能用NULL而不包括一些标准库头
int main()
{
int *ptr = NULL;
return 0;
}
产出:
prog.cpp: In function 'int main()':
prog.cpp:3:16: error: 'NULL' was not declared in this scope
C++标准将NULL定义为在某些标准库头文件中定义的实现宏。NULL的起源来自C,C++继承了它。C标准将NULL定义为0或(无效)*)0。但是在C++中有一个微妙的区别。
C++不能接受这个规范。与C不同,C++是一种强类型语言。void*对于任何类型,而C++强制执行显式强制转换),这使得C标准指定的NULL定义在许多C++表达式中毫无用处,例如:
std::string * str = NULL; //Case 1
void (A::*ptrFunc) () = &A::doSomething;
if (ptrFunc == NULL) {} //Case 2
如果NULL被定义为(无效)*)0。以上两个表达式都不能工作。
- 案例1:不编译,因为需要自动转换。
void *到std::string... - 案例2:将不会编译,因为
void *指向成员函数的指针是必需的。
因此,与C、C++标准不同,C++标准授权将NULL定义为数字文字0或0L。
那么,当我们有一个空指针常量时,还需要什么呢?NULL已经开始了?
尽管C++标准委员会提出了一个适用于C++的零定义,但这个定义也有其自身的一些问题。NULL对于几乎所有的场景都足够好,但不是全部。对于某些罕见的情况,它给出了令人惊讶和错误的结果。
#include<iostream>
void doSomething(int)
{
std::cout<<"In Int version";
}
void doSomething(char *)
{
std::cout<<"In char* version";
} int main()
{
doSomething(NULL);
return 0;
}
产出:
In Int version
很明显,其意图似乎是要调用使用char的版本。*作为参数,但当输出显示作为int版本的函数被调用时。这是因为NULL是一个数字文字。
此外,由于实现定义了NULL可以是0还是0L,因此函数重载解析可能会出现很多混乱。
样本计划:
#include <cstddef> void doSomething(int);
void doSomething(char *); int main()
{
doSomething(static_cast <char *>(0)); // Case 1
doSomething(0); // Case 2
doSomething(NULL) // Case 3
}
分析上面的片段:
- 案例1:打电话
doSomething(char *)如预期 - 案例2:打电话
doSomething(int)但也许char*需要版本是因为0也是空指针。 - 案例3:如果
NULL定义为0,,, 打电话doSomething(int)也许当doSomething(char *)可能会导致运行时出现逻辑错误。 但是,如果NULL定义为0L,,, 调用不明确,导致编译错误。
因此,根据实现的不同,相同的代码可以提供不同的结果,这显然是不可取的。当然,C++标准委员会希望纠正这一点,这是nullptr的主要动机。
所以什么是nullptr以及如何避免NULL?
C++11引入了一个新的关键字nullptr作为空指针常量。与NULL不同,它的行为不是定义的实现。它不是宏,但它有自己的类型。nullptr有std::nullptr_t...。C++11适当地定义了nullptr的属性,以避免NULL的缺点。概括一下它的性质:
财产1:它有它自己的类型std::nullptr_t和
财产2:它是隐式可转换的,可与任何指针类型或指针到成员类型相比较,但是
财产3:它不是隐式可转换的,也不是可与积分类型相比较的,除非bool...
考虑以下示例:
#include<iostream>
void doSomething(int)
{
std::cout<<"In Int version";
}
void doSomething(char *)
{
std::cout<<"In char* version";
} int main()
{
char *pc = nullptr; // Case 1
int i = nullptr; // Case 2
bool flag = nullptr; // Case 3 doSomething(nullptr); // Case 4
return 0;
}
在上面的节目中,
- 案例1:OK-财产2
- 案例2:不确定-财产3
- 案例3:OK-财产3
- 案例4:没有混淆-呼叫
char *版本,属性2和3
因此,nullptr的引入避免了好的旧空的所有问题。
你应该如何和在哪里使用nullptr?
C++11的经验法则是简单地开始使用nullptr当你以前使用空的时候。
[转]为什么要引入nullptr?的更多相关文章
- NULL、0、nullptr的区别
某些时候,我们需要将指针赋值为空指针,以防止野指针. 有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;. 也有人直接使用0值作为空指针常量,例如:int* p = 0;. ...
- 【C++11新特性】 nullptr关键字
原文链接:http://blog.csdn.net/xiejingfa/article/details/50478512 熟悉C++的童鞋都知道,为了避免“野指针”(即指针在首次使用之前没有进行初始化 ...
- 【校招面试 之 C/C++】第31题 C++ 11新特性(二)之nullptr关键字
1. 引入nullptr的原因 引入nullptr的原因,这个要从NULL说起.对于C和C++程序员来说,一定不会对NULL感到陌生.但是C和C++中的NULL却不等价.NULL表示指针不指向任何对象 ...
- C/C++杂记:NULL与0的区别、nullptr的来历
某些时候,我们需要将指针赋值为空指针,以防止野指针. 有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;. 也有人直接使用0值作为空指针常量,例如:int* p = 0;. ...
- C++ 11 nullptr关键字
熟悉C++的童鞋都知道,为了避免“野指针”(即指针在首次使用之前没有进行初始化)的出现,我们声明一个指针后最好马上对其进行初始化操作.如果暂时不明确该指针指向哪个变量,则需要赋予NULL值.除了NUL ...
- C++11新特性之四——nullptr
1. 引入nullptr的原因 引入nullptr的原因,这个要从NULL说起.对于C和C++程序员来说,一定不会对NULL感到陌生.但是C和C++中的NULL却不等价.NULL表示指针不指向任何对象 ...
- 【转载】C/C++杂记:NULL与0的区别、nullptr的来历
原文:C/C++杂记:NULL与0的区别.nullptr的来历 某些时候,我们需要将指针赋值为空指针,以防止野指针. 有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;. ...
- C++11空指针: nullptr
参考[C++11]新特性--引入nullptr NULL 在C++中, 经常会用到空指针, 一般用NULL表示空指针, 但是NULL却是这样定义的 #ifndef NULL #ifdef __cplu ...
- nullptr 与 constexpr
nullptr nullptr出现的目的自然是替换NULL的低位.C++可能会将NULL.0视为同一种东西.这取决于编译器是如何定义的,有的编译器定义NULL为 ( (void * )0) ,有的 ...
随机推荐
- 解决phpmyadmin出现: Maximum execution time of 300
在mysql用phpmyadmin导入数据的时候出现: Fatal error: Maximum execution time of 300 seconds exceeded in ... 上网查了很 ...
- App架构设计:接口的设计
安全机制的设计 现在,大部分App的接口都采用RESTful架构,RESTFul最重要的一个设计原则就是,客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时,每次请求都要带上身份验 ...
- nodejs 之简单web服务器
1.service.js var http=require('http');//引入http模块 var fs=require('fs');//fs模块 var path=require('path' ...
- nodejs之静态文件托管、 路 由、EJS 模板引擎、GET、POST
1.静态文件托管 静态文件托管:是指对于一个js方法进行封装,提高代码可读性 //fs模块 var fs=require('fs'); //path模块 var path=require('path' ...
- 域名查询是否注册的demo
import json import multiprocessing import threading import requests import xmltodict # 万网查询 def chec ...
- Maximum Likelihood 最大似然估计
Maximum Likelihood 最大似然估计 这个算法解决的问题是,当我们知道一组变量的密度分布函数与从总体采样的个体的时候,需要估计函数中的某些变量. 假设概率密度函数如下: 一般来说,为了计 ...
- 【github】git常用命令和node项目
这是之前在本地搞的一个小东西.因为之前电脑经常会很卡.后来发现任务管理器中多了两个不知名的进程:chromgpu.exe和flrefox.exe 乍一看以为和chrome和firefox两个浏览器有关 ...
- Day06:抽象类、接口和内部类(上)
JVAV中的常量 什么是常量? 常量就是不会变化的数值 为什么需要常量? 方便使用(调用)不会变化的数值 特性 不能修改 所有对象共享 常量一定是成员 定义 public static final 类 ...
- 【计算机视觉】ViBe - a powerful technique for background detection and subtraction in video sequences
转自:http://blog.csdn.net/stellar0/article/details/8777283 作者:星zai ViBe算法:ViBe - a powerful technique ...
- GitHub高级搜索
GitHub是开发目前最为活跃的开源网站和代码托管地,虽然我们经常使用GitHub,关注各种开源项目,但可能有很多人并不太了解GitHub的搜索功能的使用.GitHub提供了简单搜索和高级搜索,高级 ...