C++高级特性:nullptr和NULL的区别(十)

server/2024/10/19 21:38:33/
1、NULL和0
  • 在C语言标准定义中,NULL的定义为(void *)0

    这样的代码意味着可以进行强制类型转换一个void *类型的指针到任意类型的指针

    #define NULL (void*)0
    char *p = NULL;
    
  • C++11之后NULL被定义为0,此时可以认为NULL不完全是一个空指针。

    #ifndef __cplusplus
    #define NULL ((void *)0)
    #else   /* C++ */
    #define NULL 0
    #endif  /* C++ */
    
    • C++是一门类型安全的语言,*无法将一个void 类型的指针隐式转换为其他类型

      char *p = 0;
      char *p1 = NULL;                    
      char *p2 = (void *)0;                              // 报错
      char *p3 = reinterpret_cast<char*>(NULL);          // 强转可以
      
    • 而这样又会引入另外一个重载的二义性问题

      因为NULL的值实际是0,但是char 也可以接收一个NULL(0)值,但是NULL又被定义为0值,这样就会导致一个二义性问题。

      void func(int )
      {std::cout << "func(int)" << std::endl;
      }
      void func(char *)
      {std::cout << "func(char *) " << std::endl;
      }void test1()
      {func(0);                                        // 调用func(int)
      //    func(NULL);                                   // 报错func(reinterpret_cast<char *>(NULL));           //强转可以调用func(char *)
      }
      
2、nullptr
  • 为了解决上面带来的二义性问题,C++11之后引入了nullptr来专门区分0和空指针。

  • nullptr的类型为std::nullptr_tnullptr是一个std::nullptr_t的纯右值

  • nullptr能够隐式的转换为任何指针,因此空指针的时候推荐使用nullptr

  • 而通过nullptr就可以解决上面的二义性问题

    void test2()
    {func(0);                                        // 调用func(int)func(nullptr);                                  // 调用func(char *)
    }
    
3、nullptr_t的定义
  • 可以看到nullptr被定义为nullptr_t类型
  • 同时nullptr_t的类型长度与void *长度相同
namespace std
{typedef __SIZE_TYPE__ 	size_t;typedef __PTRDIFF_TYPE__	ptrdiff_t;#if __cplusplus >= 201103Ltypedef decltype(nullptr)	nullptr_t;
#endif
}
static_assert(sizeof(std::nullptr_t) == sizeof(void *));
  • nullptr_t也可以定义一个其他指针的空指针对象并且与nullptr有相同的能力,而且被创建的对象是一个左值
void test3()
{std::nullptr_t null1;std::nullptr_t null2;std::cout << "&null1 = " << &null1 << std::endl;std::cout << "&null2 = " << &null2 << std::endl;
//    std::cout << "&nullptr = " << &nullptr << std::endl;            //报错,右值没有地址
}

http://www.ppmy.cn/server/3483.html

相关文章

Sql server备份还原sql语句

使用备份文件指定新的数据库名称 USE MASTER --这里注意要使用MASTER&#xff0c;以免出现待还原库被占用的情况 RESTORE DATABASE [tsw_test] --为待还原库名 FROM DISK C:\Program Files\Microsof…

Leetcode 25. K 个一组翻转链表

题目链接&#xff1a; 25. K 个一组翻转链表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/reverse-nodes-in-k-group/description/ 题目&#xff1a; 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。…

Python | Leetcode Python题解之第39题组合总和

题目&#xff1a; 题解&#xff1a; from typing import Listclass Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:def dfs(candidates, begin, size, path, res, target):if target < 0:returnif target 0:res.append(p…

Mac上的PD虚拟机安装parallels tools问题

本文主要记录mac上的虚拟机软件安装好centos7.9的时候安装parallels tools的错误的解决办法&#xff1a; Centos 7.9虚拟机安装parallels tools 前言 在centos高版本上安装parallells tools时会报错&#xff0c;具体错误信息可以在/var/log/parallels.log文件中查看。 本文…

CH58X使用USB HID进行IAP注意事项——笔记

CH58X使用USB HID进行IAP注意事项——笔记 一、背景 基础 单片机使用CH582M&#xff0c;并使用USB HID进行IAP升级。方案 方案1&#xff1a;APPBOOT方案&#xff0c;可以只安装APP就可以运行&#xff0c;APP中后续安装BOOT程序和后面更新也方便。 方案2&#xff1a;经典IAP方…

UE5(基础动作)多人游戏制作蹲伏

1.创建输入操作&#xff0c;IA_Crouch 在输入映射中添加 IA_Crouch,在触发器中创建两个索引&#xff0c;已按下已松开来创建蹲伏输入。 蹲伏操作必须要勾选角色-角色移动-crouch勾选可蹲伏否则你的人物无法真正蹲下。 为蹲伏创建函数&#xff0c;创建布尔来判断是否蹲伏。 通过…

使用 Docker 部署 SurveyKing 调查问卷系统

1&#xff09;SurveyKing 介绍 SurveyKing 是一款功能强大、操作简便的开源问卷系统。它不仅满足了用户对问卷调查的基本需求&#xff0c;还提供了丰富的逻辑设置和灵活的问题设置&#xff0c;使得问卷制作更加智能化和个性化。此外&#xff0c;SurveyKing 还具有快速部署和安全…

服务器数据恢复—xfs文件系统节点、目录项丢失的数据恢复案例

服务器数据恢复环境&#xff1a; EMC某型号存储&#xff0c;该存储内有一组由12块磁盘组建的raid5阵列&#xff0c;划分了两个lun。 服务器故障&#xff1a; 管理员为服务器重装操作系统后&#xff0c;发现服务器的磁盘分区发生改变&#xff0c;原来的sdc3分区丢失。由于该分区…