欢迎光临
我们一直在努力

C++面试总结(1)

一、C++ 基础语法

1. 指针和引用的区别

相同点
  • 均可间接访问变量
  • 支持多态
  • 函数传参时避免拷贝
  • 引用是指针的语法糖,汇编层面通过指针实现(实际传入地址)
  • 不同点

    表格

    特性指针引用
    概念 存储变量的内存地址 已存在变量的别名
    初始化 定义时无需初始化 定义时必须初始化
    指向性 可随时指向同类型任意实体 初始化后不能引用其他实体
    空值 存在 NULL 指针,操作需检查 无 NULL 引用,无需检查
    sizeof 含义 始终为地址空间字节数(32 位 4 字节) 引用类型的实际大小
    自加操作 指针向后偏移一个类型大小 引用的实体值 + 1
    多级支持 支持多级指针(**p) 无多级引用
    访问方式 需显式解引用(*p) 编译器自动处理,直接使用
    安全性 相对较低,易出现野指针 相对更高
    适用场景
    • 指针:动态内存管理、实现复杂数据结构(链表、树等)
    • 引用:操作符重载、返回引用实现链式调用

    2. static 关键字

    用于控制变量和函数的生命周期、作用域、访问权限,主要分为 4 类:

  • 静态局部变量:函数内修饰,程序整个生命周期存在,默认初始化为 0,仅初始化一次
  • 静态成员变量:类内修饰,所有类对象共享,必须在类外单独初始化
  • 全局静态变量 / 函数:作用域限制在当前.cpp 文件,避免跨文件命名冲突
  • 静态成员函数:类内修饰,属于类而非实例,可通过类名直接调用,仅能访问静态成员变量
  • 问题:解决不同编译单元 static 变量析构顺序不一致
    • 问题根源:不同.cpp 文件的静态变量初始化顺序未定义,析构顺序与初始化相反,若 A 析构时依赖已析构的 B,程序崩溃
    • 解决方案:静态局部变量 + 单例模式
      • C++11 保证函数内局部静态变量初始化线程安全,且在 main 后首次调用时初始化
      • 单例析构早于全局变量,即使析构后调用 getInstance (),其内存仍存在,可有限操作

    3. inline 内联函数

  • 对编译器的请求性指令,编译器可拒绝(如函数体过长)
  • 编译时将函数体替换函数调用,避免压栈、跳转、返回等调用开销
  • 适用于短小且频繁调用的函数
  • 会进行严格的类型检查,区别于宏定义
  • 4. new/malloc 与 delete/free 区别

    new & malloc 核心区别

    表格

    特性new/deletemalloc/free
    失败处理 分配失败抛出异常 分配失败返回 NULL
    内存大小 自动计算,无需指定 需显式指定字节数
    类型处理 自动推导类型,无需强转 返回 void*,需强制类型转换
    重载支持 operator new/delete 可重载 不可重载
    对象处理 调用构造 / 析构函数 仅分配 / 释放内存,不处理对象
    语言属性 C++ 运算符 C 标准库函数
    delete & free 核心区别
  • 类型安全性:delete 是类型安全的,free 参数为 void*,无类型检查
  • 对象析构:delete 先调用析构函数再释内存;delete [] 对数组逐个调用析构(从后往前);free 直接释内存,不调用析构
  • 数组释放:delete [] 专为 new [] 分配的数组设计;free 无法识别数组大小,不适用于数组释放
  • delete[]如何知道要析构多少元素?

    new[]分配内存时,会分配size_t大小的空间,用于存储数组元素个数 delete[]p; 指针左偏移sizeof(size_t)就可以拿到数组个数,从而知道析构多少元素

    5. 函数指针和指针函数

    函数指针
    • 指向函数的指针变量,存储函数地址,支持运行时动态调用函数
    • 语法:返回值类型 (*指针名)(参数列表) = &函数名;
    • 示例:

      int add(int a, int b) { return a+b; }
      int (*ptr)(int,int) = &add;
      int res = (*ptr)(3,4); // 调用结果为7

    • 适用场景:回调函数、动态加载库的函数调用
    指针函数
    • 返回值为指针类型的普通函数,本质是函数,非指针
    • 语法:返回值类型* 函数名(参数列表);
    • 注意:避免返回局部变量的指针(局部变量出作用域销毁,会产生野指针)

    6. 强制类型转换

    C++ 提供 4 种显式类型转换,替代 C 语言的隐式转换,更安全、语义更清晰:

    表格

    转换类型适用场景安全性特点
    static_cast 基本类型转换、上行转换(派生→基类)、任意类型转 void 中等 无运行时类型检查,下行转换(基类→派生)不安全
    dynamic_cast 存在虚函数的父子类之间的下行转换 有运行时类型检查;指针转换失败返回 nullptr,引用失败抛出异常
    reinterpret_cast 任意指针 / 引用间转换、指针与整型转换 最低(最危险) 仅重新解释二进制位,不做类型检查
    const_cast 移除变量的 const/volatile 属性 中等 仅修改常量性,不改变类型;常量指针→非常量指针,仍指向原对象

    赞(0)
    未经允许不得转载:171主机测评 » C++面试总结(1)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址