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

一道C++面试题关于nullptr的知识点

在这里插入图片描述

一、关于nullptr的面试题

下面的代码在什么情况下,没有问题。

int main() {
    MyClass* ptr = nullptr;
    ptr->Function1();  
    return 0;
}

通常来说,ptr是一个空指针,用空指针来调用函数是不可能的,怎么肯能正确呢?

二、回顾一下nullptr的基础知识

nullptr 是 C++11 引入的一个关键字,用于表示空指针,它解决了 C++ 此前在空指针表示方面存在的一些问题,以下是关于它的基础知识介绍:

  • 引入背景
    • 在 C++98 标准中,空指针通常用宏 NULL 来表示,而 NULL 被定义为 ((void*)0) ,本质上是一个值为0的整数常量。这种定义方式在函数重载场景下容易引发歧义。例如,当一个函数接受 int 指针参数,另一个函数接受 int 类型参数时,传入 NULL 可能导致编译器调用错误的函数,因为 NULL 既能被当作指针类型,也能被当作整型。
    • 为了消除这类二义性,C++11 引入了 nullptr
  • 类型
    • nullptr 的类型是 std::nullptr_t,这是一种独特的类型,它可以隐式转换为任何指针类型,但不能转换为非指针类型,如整数类型。这就保证了类型安全,避免像过去使用 NULL 时可能出现的混淆。例如:
void foo(int*);
void foo(int);

int main() {
    foo(nullptr);  // 正确调用foo(int*)
    // foo(NULL);  // 在旧代码中,这会有歧义,可能导致错误调用
    return 0;
}
  • 用法
    • 用于初始化指针变量,明确地将指针设置为空状态。例如:
int* p = nullptr;
class MyClass;
MyClass* objPtr = nullptr;
- 作为函数参数传递,当函数期望接收一个指针参数,并且当前没有有效的指针可传时,使用 `nullptr` 清晰表明“这里没有指向有效对象的指针”:
#include <iostream>
#include <memory>

void printMessage(const char* msg) {
    if (msg!= nullptr) {
        std::cout << msg << std::endl;
    } else {
        std::cout << "No message." << std::endl;
    }
}

int main() {
    printMessage(nullptr);
    return 0;
}
  • 0NULL 的区别
    • 0 是一个整型常量,虽然在很多情况下能当作空指针使用,但编译器只是做了隐式转换,这种隐式转换正是造成类型混淆的根源。NULL 本质上等同于 0,同样有潜在风险。而 nullptr 从类型上就杜绝了与整型混淆的可能性,使代码语义更加清晰,编译时也能更精准地处理指针相关逻辑。

三、如何保证面试题能够不出问题

从上面的基础知识回顾中,可以发现,nullptr不同于0和NULL,它实际上是一个类型。如果在运行时,用该指针调用,应该是会报错的,但是如果是在编译时,就有效。考虑下面的代码:

class MyClass {
public:
    static void Function1() {
        std::cout << "This is a static function." << std::endl;
    }
};
int main() {
    MyClass* ptr = nullptr;
    ptr->Function1();  
    return 0;
}

在上述示例中,虽然ptrnullptr,但由于静态函数不依赖于对象的实例,而是属于类本身,所以可以通过nullptr转换后的指针来调用静态函数。实际上,在这种情况下,即使指针为nullptr,编译器在解析函数调用时,会直接根据指针的类型找到对应的类和静态函数进行调用,而不会对指针进行解引用操作,因此不会出现空指针解引用的错误。


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

相关文章:

  • clickhouse Cannot execute replicated DDL query, maximum retries exceeded报错解决
  • Eplan 布局图中的宏/设备/安装板比例缩放
  • 【期末复习】一、操作系统概论
  • 【OpenCV】使用Python和OpenCV实现火焰检测
  • STLG_01_05_程序设计C语言 - 数据类型概念解析
  • 《从入门到精通:蓝桥杯编程大赛知识点全攻略》(一)-递归实现指数型枚举、递归实现排列型枚举
  • Echarts+vue电商平台数据可视化——webSocket改造项目
  • ES数据管理
  • UnityRenderStreaming使用记录(三)
  • 远程服务器训练模型,使用tmux防止训练终止
  • Go语言方法和接收器类型详解
  • vue3配置测试环境、开发环境、生产环境
  • UNI-APP_i18n国际化引入
  • 无人机技术突飞猛进,超大集群飞行技术详解
  • http报头解析
  • 爬虫与反爬虫实现全流程
  • STM32-I2C通信
  • 安装PostgreSQL后的初始化操作
  • 浏览器--解决页面没刷新的问题(清除所有缓存)
  • 【从零开始入门unity游戏开发之——C#篇35】C#自定义类实现Sort自定义排序
  • net core程序部署到 iis 出现跨域问题
  • Spring Boot JPA Oracle 最佳实践 20 条
  • 《迁移学习与联邦学习:推动人工智能发展的关键力量》
  • APP怎么抓取原生日志 - Android篇
  • springboot3.X 无法解析parameter参数问题
  • vue.js scoped样式冲突