C++ 从 0 入门(六)|C++ 面试必知:运算符重载、异常处理、动态内存进阶(终极补充)

大家好,我是网域小星球。

本篇是 C++ 面试补充的最后一篇,聚焦 3 个面试高频进阶考点------ 运算符重载、异常处理、动态内存进阶,都是基础面试中 "拉开差距" 的知识点,也是笔试常考的手撕题。学完这两篇补充,你的 C++ 面试基础会更扎实,轻松应对面试官的延伸提问,代码全部 VS2022 可运行。

目录

一、核心学习目标(面试导向)

二、运算符重载(笔试手撕高频,面试必问)

[1. 核心概念](#1. 核心概念)

[2. 核心规则(面试必背)](#2. 核心规则(面试必背))

[3. 常用运算符重载(笔试手撕示例)](#3. 常用运算符重载(笔试手撕示例))

[示例 1:重载 + 运算符(成员函数)](#示例 1:重载 + 运算符(成员函数))

[示例 2:重载 << 运算符(友元函数,高频)](#示例 2:重载 << 运算符(友元函数,高频))

面试常问

三、异常处理(try-catch-throw,面试必问)

[1. 核心作用](#1. 核心作用)

[2. 核心语法(面试必背)](#2. 核心语法(面试必背))

面试常问

四、动态内存进阶(new/delete、智能指针,面试高频)

[1. C++ 动态内存管理(new/delete,替代 C 语言 malloc/free)](#1. C++ 动态内存管理(new/delete,替代 C 语言 malloc/free))

核心区别(面试必问)

代码示例

面试坑点

[2. 智能指针入门(面试高频,了解即可)](#2. 智能指针入门(面试高频,了解即可))

核心作用

常用智能指针(面试必记)

代码示例(unique_ptr,最基础)

面试常问

五、本章核心总结(面试速记)


一、核心学习目标(面试导向)

  1. 掌握 运算符重载(语法 + 常用重载,笔试手撕题)
  2. 理解 异常处理(try-catch-throw)(面试必问用法)
  3. 吃透 动态内存进阶(new/delete、智能指针入门,避免内存泄漏)
  4. 掌握三大知识点的面试标准答案和代码写法

二、运算符重载(笔试手撕高频,面试必问)

1. 核心概念

C++ 允许重载运算符(如 +、-、*、==、<< 等),让自定义类的对象,能像内置类型(int、double)一样使用运算符,提高代码简洁性。

2. 核心规则(面试必背)

  1. 不能重载的运算符(牢记):..*::? :sizeof
  2. 重载运算符的优先级、结合性,与原运算符一致;
  3. 运算符重载本质是函数,分为 成员函数重载友元函数重载

3. 常用运算符重载(笔试手撕示例)

示例 1:重载 + 运算符(成员函数)

实现两个 Person 对象的年龄相加:

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

class Person
{
public:
    int age;
    Person(int a) { age = a; }

    // 重载 + 运算符(成员函数)
    Person operator+(const Person& p)
    {
        Person temp(0);
        temp.age = this->age + p.age; // this指向当前对象
        return temp;
    }
};

int main()
{
    Person p1(20), p2(18);
    Person p3 = p1 + p2; // 等价于 p1.operator+(p2)
    cout << "年龄和:" << p3.age << endl; // 输出38
    return 0;
}
示例 2:重载 << 运算符(友元函数,高频)

实现 cout 直接输出自定义对象(笔试常考):

cpp 复制代码
class Person
{
private:
    string name;
    int age;
    // 友元函数重载 <<
    friend ostream& operator<<(ostream& cout, const Person& p);

public:
    Person(string n, int a) : name(n), age(a) {}
};

// 友元函数重载 <<(类外定义)
ostream& operator<<(ostream& cout, const Person& p)
{
    cout << "姓名:" << p.name << ",年龄:" << p.age;
    return cout; // 返回cout,支持链式输出(如cout << p1 << p2)
}

int main()
{
    Person p("张三", 20);
    cout << p << endl; // 直接输出对象,等价于 operator<<(cout, p)
    return 0;
}
面试常问
  • 为什么 << 运算符重载要用友元函数?答:因为 cout 是 ostream 类的对象,若用成员函数重载,左操作数必须是当前类对象(如 p << cout),不符合使用习惯;友元函数可让左操作数是 cout,右操作数是自定义对象,符合常规用法。

三、异常处理(try-catch-throw,面试必问)

1. 核心作用

捕获程序运行时的异常(如除 0、数组越界、动态内存申请失败),避免程序直接崩溃,提高程序健壮性。

2. 核心语法(面试必背)

cpp 复制代码
try
{
    // 可能出现异常的代码
    throw 异常值; // 抛出异常
}
catch (异常类型1)
{
    // 捕获并处理异常类型1
}
catch (异常类型2)
{
    // 捕获并处理异常类型2
}
catch (...)
{
    // 捕获所有类型异常(兜底)
}
  1. 代码示例(面试常考场景)
cpp 复制代码
#include <iostream>
using namespace std;

// 除法函数,抛出除0异常
int divide(int a, int b)
{
    if (b == 0)
    {
        // 抛出异常(可抛出任意类型:int、string等)
        throw "除0错误!";
    }
    return a / b;
}

int main()
{
    int x = 10, y = 0;
    try
    {
        int res = divide(x, y); // 可能出现异常
        cout << "结果:" << res << endl;
    }
    catch (const char* err) // 捕获char*类型异常
    {
        cout << "异常捕获:" << err << endl; // 输出异常信息
    }
    catch (...) // 兜底,捕获所有未匹配的异常
    {
        cout << "未知异常!" << endl;
    }

    // 异常处理后,程序继续执行(不会崩溃)
    cout << "程序正常执行完毕" << endl;
    return 0;
}
面试常问
  1. C++ 异常处理的优点?答:分离异常检测和异常处理代码,提高代码可读性、可维护性;避免程序直接崩溃,增强程序健壮性。
  2. throw 抛出的异常,必须被 catch 捕获吗?答:不一定;若未被 catch 捕获,会调用系统默认异常处理函数,程序依旧会崩溃。

四、动态内存进阶(new/delete、智能指针,面试高频)

1. C++ 动态内存管理(new/delete,替代 C 语言 malloc/free)

核心区别(面试必问)
对比维度 new/delete(C++) malloc/free(C)
本质 运算符(不是函数) 库函数
类型检查 有严格类型检查 无类型检查(返回 void*)
构造 / 析构 自动调用构造 / 析构 不调用,需手动初始化 / 释放
内存分配 直接分配对应类型内存 需手动计算内存大小
代码示例
cpp 复制代码
#include <iostream>
using namespace std;

class Person
{
public:
    Person() { cout << "构造调用" << endl; }
    ~Person() { cout << "析构调用" << endl; }
};

int main()
{
    // 1. 动态分配单个对象
    Person* p1 = new Person; // 自动调用构造
    delete p1; // 自动调用析构,释放内存
    p1 = nullptr; // 置空,避免野指针

    // 2. 动态分配数组
    Person* p2 = new Person[3]; // 调用3次构造
    delete[] p2; // 必须加[],否则只调用1次析构,内存泄漏
    p2 = nullptr;

    return 0;
}
面试坑点
  • 动态分配数组时,delete 必须加 [],否则会导致内存泄漏;
  • new 申请内存失败时,会抛出 bad_alloc 异常(C++11 后);
  • 避免内存泄漏:new 和 delete 必须成对出现,最好用智能指针管理。

2. 智能指针入门(面试高频,了解即可)

核心作用

自动管理动态内存,无需手动 delete,彻底避免内存泄漏(面试常问 "如何避免内存泄漏",智能指针是核心答案)。

常用智能指针(面试必记)
  1. unique_ptr:独占所有权,一个智能指针只能指向一个对象,不能拷贝;
  2. shared_ptr:共享所有权,多个智能指针可指向同一个对象,自动计数,计数为 0 时释放内存;
  3. weak_ptr:辅助 shared_ptr,解决循环引用问题。
代码示例(unique_ptr,最基础)
cpp 复制代码
#include <iostream>
#include <memory> // 智能指针头文件
using namespace std;

class Person
{
public:
    ~Person() { cout << "析构调用,内存释放" << endl; }
};

int main()
{
    // 智能指针自动管理内存,无需手动delete
    unique_ptr<Person> p(new Person);
    // 自动释放,无需写delete
    return 0;
}
面试常问
  • 如何避免 C++ 内存泄漏?答:1. new 和 delete 成对出现;2. 使用智能指针(unique_ptr/shared_ptr);3. 避免野指针,及时置空;4. 析构函数中释放动态内存。

五、本章核心总结(面试速记)

  1. 运算符重载:让自定义对象可使用运算符,<< 重载常用友元,不能重载 5 个特殊运算符;
  2. 异常处理:try 捕获、throw 抛出、catch 处理,避免程序崩溃,提高健壮性;
  3. 动态内存:new/delete 自动调用构造 / 析构,智能指针可自动管理内存,避免泄漏;
相关推荐
晚会者荣1 小时前
红黑树的插入(有图)
c++
FL16238631292 小时前
基于C#winform部署软前景分割DAViD算法的onnx模型实现前景分割
开发语言·算法·c#
2601_949817922 小时前
大厂Java进阶面试解析笔记文档
java·笔记·面试
郭wes代码2 小时前
大三Java课设:一行行敲出来的贪吃蛇,老师以为我是CV的
java·开发语言
John.Lewis2 小时前
C++进阶(12)附加学习:STL之空间配置器(了解)
开发语言·c++·笔记
汉克老师2 小时前
GESP2023年12月认证C++三级( 第三部分编程题(2、单位转换))
c++·string·单位转换·gesp三级·gesp3级
C雨后彩虹2 小时前
最多等和不相交连续子序列
java·数据结构·算法·华为·面试
23471021273 小时前
4.16 学习笔记
开发语言·软件测试·python
014-code3 小时前
日志规范:怎么写才不算写废话
java·开发语言·设计模式·日志