2. C++语言核心高频问题:虚函数与多态、智能指针、内存管理、RAII

面试官在本主题中重点考察对C++三大核心机制(运行时多态、资源管理、异常安全)的理解深度。要求不仅知道“怎么用”,还要能解释“为什么这样设计”以及“对比其他方案的优缺点”。以下是高频问题的回答框架与实战要点。

虚函数定义与原理 虚表(vtable)与虚指针 动态绑定与多态条件 纯虚函数与抽象类 性能开销与注意事项 回答框架:定义 → 机制 → 条件 → 抽象 → 开销

📊 核心知识点速查表

主题关键概念常见考查点避坑提醒
虚函数与多态vptr/vtable、动态绑定、重写(override)虚函数能否内联?构造/析构中调用虚函数的行为不要忘记virtual析构函数
智能指针shared_ptr/weak_ptr/unique_ptr、引用计数、循环引用控制块大小、线程安全、与裸指针混用风险避免shared_ptr循环引用导致内存泄漏
RAII资源获取即初始化、栈对象管理、异常安全与智能指针关系、自定义RAII封装、ScopeGuard析构函数不可抛出异常
内存管理new/delete与malloc/free、对象池、内存对齐placement new、operator new重载、内存碎片new[]必须对应delete[]

❓ 面试问题:请解释C++虚函数的实现原理,以及多态在运行时的行为。

🎯 面试官考察点:

  • 是否理解虚表(vtable)和虚指针(vptr)的内存布局
  • 能否说清动态绑定的触发条件
  • 是否知道虚函数在构造函数/析构函数中的特殊行为

📝 回答框架: 定义虚函数 → vptr与vtable关系 → 动态绑定过程 → 纯虚函数与抽象类 → 性能与限制

💬 简短示例回答: 每个含有虚函数的类有一个虚函数表,对象头中存储vptr指向该表。调用虚函数时通过vptr找到实际函数地址。存在继承且函数签名相同时,派生类覆盖基类虚函数。注意构造/析构期间对象类型是当前构造的类,不会发生动态绑定。

🔍 可能追问: 虚函数能否被声明为内联?多继承下的vptr布局?C++11的final和override作用?

⚠️ 避坑提醒: 不要在构造函数或析构函数中调用虚函数,因为此时派生类部分尚未构造/已被析构,动态绑定无效。

❓ 面试问题:请比较std::unique_ptr、std::shared_ptr和std::weak_ptr的区别及使用场景。

🎯 面试官考察点:

  • 是否掌握三种指针的所有权语义
  • 能否说明引用计数的工作原理及线程安全问题
  • 是否知道如何避免循环引用

📝 回答框架: 独占所有权 vs 共享所有权 → shared_ptr引用计数 & 控制块 → weak_ptr解决循环引用 → 性能差异与使用建议

💬 简短示例回答: unique_ptr独占资源,轻量但禁止拷贝;shared_ptr通过控制块管理引用计数,支持拷贝但开销较大;weak_ptr配合shared_ptr使用,不增加引用计数,常用于观察者模式或打破循环。优先使用unique_ptr,需要共享时再考虑shared_ptr。

🔍 可能追问: make_shared与直接new构造shared_ptr的区别?控制块内存位置?自定义删除器的实现?

⚠️ 避坑提醒: 不要将同一个裸指针分别构造两个shared_ptr,会导致两次析构;使用weak_ptr.lock()前务必检查是否过期。

❓ 面试问题:RAII的核心思想是什么?如何利用RAII实现资源管理及异常安全?

🎯 面试官考察点:

  • 是否理解RAII与异常安全的关系
  • 能否举例说明自定义RAII封装(如锁、文件句柄)
  • 是否了解C++11的移动语义对RAII的优化

📝 回答框架: 资源获取即初始化 → 析构函数自动释放 → 异常安全基本保证 → 智能指针是RAII典范 → 移动语义避免资源复制

💬 简短示例回答: RAII将资源生命周期绑定到栈对象:构造函数获取资源,析构函数安全释放。例如std::lock_guard自动管理mutex,即使函数中途抛出异常,锁也会被释放。这是C++异常安全的基础,也避免了手动new/delete配对。

🔍 可能追问: 什么是“强异常安全保证”?copy-and-swap技术如何实现?RAII与垃圾回收的对比?

⚠️ 避坑提醒: RAII对象的析构函数必须不能抛出异常;如果需要多个资源,建议按依赖顺序封装为嵌套RAII对象,避免资源泄漏。

💡 面试加分技巧: 在回答虚函数问题时,主动画出内存布局图(vptr、vtable、对象内容)会极大提升面试官印象;提到C++11/14/17特性(如override、final、std::make_shared)展示持续学习能力。

📌 记忆口诀: 虚函数靠表,多态靠指针;智能指针三种权,RAII保安全;内存管理先配对,构造析构不乱配。

⚠️ 高阶提醒: 面试高频陷阱——问“智能指针循环引用如何排查?”回答:使用weak_ptr打断闭环,或使用工具如Valgrind/AddressSanitizer检测引用计数泄漏。