如何通过C++面试:热门问题与答案

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

如何通过C++面试:附带代码示例的经典问题



C++面试是开发者面临的最严峻挑战之一。这门语言将底层编程的强大功能与现代面向对象和模板范式相结合。要成功通过面试,不仅需要掌握语法,还要理解内存、编译器以及标准库的工作原理。本文将解析C++面试中最常被问及的10大问题,并附带详细解答与代码示例。



1. 什么是RAII?为什么需要它?

RAII(资源获取即初始化)是C++的核心编程范式之一。其本质是:资源(内存、文件、互斥锁)在对象的构造函数中获取,并在析构函数中释放。这确保了即使发生异常也能正确清理资源。



错误代码示例(未使用RAII):

void process() {    int* ptr = new int(42);    // ... 可能抛出异常的代码    delete ptr; // 若在delete前发生异常,会导致内存泄漏}


使用RAII的示例(采用std::unique_ptr):

#include <memory>

void process() { std::unique_ptr<int> ptr = std::make_unique<int>(42); // ... 可能包含异常的代码 // 当ptr离开作用域时自动释放内存}


问及此问题的原因:RAII是C++安全资源管理的基础。没有它,编写可靠代码将无从谈起。



2. 虚函数与纯虚函数有何区别?

虚函数(virtual)可以在派生类中被重写,但在基类中有默认实现。纯虚函数(= 0)在基类中无实现,并使该类成为抽象类——无法实例化该类的对象。



示例:

class Base {public:    virtual void foo() { std::cout << "Base foo"; }   // 虚函数    virtual void bar() = 0;                               // 纯虚函数};

class Derived : public Base {public: void foo() override { std::cout << "Derived foo"; } void bar() override { std::cout << "Derived bar"; }};


追问:虚函数表(vtable)如何工作?编译器会为每个包含虚方法的类创建一张虚函数表。每个对象都包含一个指向该表的指针(vptr)。调用虚函数时,通过虚函数表实现动态分派。



3. C++中有哪些智能指针?何时使用它们?

C++11引入了三种智能指针:

  • std::unique_ptr — 独占所有权。不可复制,只能移动。适用于单一所有者的资源管理。
  • std::shared_ptr — 共享所有权。采用引用计数机制。适用于多个对象需要共享同一资源的情况。
  • std::weak_ptr — 不拥有资源,但可观察shared_ptr。用于打破循环引用。


unique_ptr使用示例:

#include <memory>

class MyClass { /* ... */ };

void example() { auto ptr = std::make_unique<MyClass>(); // auto ptr2 = ptr; // 错误!不可复制 auto ptr3 = std::move(ptr); // 正确,移动操作}


使用shared_ptr和weak_ptr防止循环引用示例:

struct Node {    std::shared_ptr<Node> next;    std::weak_ptr<Node> prev; // 使用weak_ptr避免循环引用};


4. 什么是移动语义与std::move?

移动语义允许将资源从一个对象"移动"到另一个对象,而非复制。这对于临时对象或复制开销较大的情况(例如std::string或

博客

书籍推荐