当前位置: 首页 > article >正文

【C++】C++的nullptr和NULL

在 C++ 中,nullptrNULL 都可以表示一个空指针(空地址),但它们的定义和用法存在显著差异。


1. NULL 是什么?

  • NULL 的定义:
    在 C 和早期的 C++ 中,NULL 通常被定义为整数 0,其定义如下(来自标准库 <cstddef><stddef.h>):
    #define NULL 0
    
  • 行为:
    • NULL 是一个预处理器宏,用来表示一个整数常量 0
    • 由于 NULL 被定义为 0,在某些上下文中可能会引发模糊性或类型问题。例如:
      void func(int);
      void func(void*);
      
      func(NULL); // 调用 func(int) 而不是 func(void*),因为 NULL 是 0(int 类型)。
      

2. nullptr 是什么?

  • nullptr 的定义:

    • nullptr 是在 C++11 引入的新关键字,表示空指针常量,它是一个专用的指针类型。
    • 它的类型是 std::nullptr_t,可以隐式转换为任何指针类型,但不能转换为整数类型。
  • 行为:

    • nullptr 是一种明确的空指针类型,避免了 NULL 带来的类型模糊问题。例如:
      void func(int);
      void func(void*);
      
      func(nullptr); // 明确调用 func(void*),因为 nullptr 是空指针类型。
      

3. 区别对比

特性NULLnullptr
引入版本C 和早期的 C++C++11
定义宏,通常定义为 #define NULL 0关键字,类型为 std::nullptr_t
类型整数常量,通常是 int专用类型 std::nullptr_t
指针转换可隐式转换为指针类型,但可能引起歧义可隐式转换为任何指针类型,无歧义
整数转换是一个整数,参与整数运算不是整数,不能参与整数运算
安全性易引起类型混淆,存在潜在的歧义问题类型安全,避免了指针和整数混淆的问题
适用性向后兼容的代码,旧式 C++ 项目现代 C++ 编程,推荐使用

4. **使用 **

  • 推荐使用 nullptr

    • nullptr 是类型安全的,不会与整数混淆。
    • 对于 C++11 及以上的代码,应始终使用 nullptr,它是现代 C++ 编程的标准。
  • 在旧代码中使用 NULL

    • 如果项目是混合 C 和 C++,或者使用了旧式代码,NULL 可能仍然会被使用。
    • 但在新开发中,应尽量避免使用 NULL,改用 nullptr

5. **示例 **

展示了 nullptrNULL 的不同效果:

#include <iostream>
using namespace std;

void func(int) {
    cout << "func(int) called" << endl;
}

void func(void*) {
    cout << "func(void*) called" << endl;
}

int main() {
    func(NULL);    // 输出:func(int) called,因为 NULL 是整数类型
    func(nullptr); // 输出:func(void*) called,因为 nullptr 是空指针类型

    // 类型检查
    int* p1 = NULL;       // 合法,NULL 转换为 int*
    // int val = nullptr; // 错误,nullptr 不能隐式转换为 int
    int* p2 = nullptr;    // 合法,nullptr 是类型安全的空指针

    return 0;
}

http://www.kler.cn/a/411337.html

相关文章:

  • 小程序基础:流程。
  • JAVA---IO
  • 国土变更调查拓扑错误自动化修复工具的研究
  • 【AIGC】如何准确引导ChatGPT,实现精细化GPTs指令生成
  • ubuntu20.04中编译安装gcc 9.2.0
  • 单点修改,区间求和或区间询问最值(线段树)
  • vue的理解
  • 鸿蒙学习自由流转与分布式运行环境-价值与架构定义(1)
  • 【C++】顺序容器(二):顺序容器操作
  • C++11新特性探索:Lambda表达式与函数包装器的实用指南
  • 极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【四】
  • STM32中I2C总线中,允许从机控制SCL总线吗?
  • uname -m(machine) 命令用于显示当前系统的机器硬件架构(Unix Name)
  • 什么是 C++ 中的多继承?它有哪些优缺点?什么是虚继承?为什么要使用虚继承?
  • OSPTrack:一个包含多个生态系统中软件包执行时生成的静态和动态特征的标记数据集,用于识别开源软件中的恶意行为。
  • Linux 网络编程之UDP套接字
  • win10中使用ffmpeg的filter滤镜
  • gocv调用opencv添加中文乱码的解决方案
  • 《Java 对象池技术:性能优化的利器》
  • 堆——acwing
  • shell脚本实现自动化交互功能
  • java大视频分片上传
  • 【Conda 】Conda 配置文件详解:优化你的包管理与环境设置
  • 【Nginx】核心概念与安装配置解释
  • Docker login 报证书存储错误的解决办法
  • (完整版Word原件)智慧产业园区能源管控系统解决方案,能源管理系统解决方案-能源数字化监控解决方案,工业能源管理系统解决方案,园区能源管理