C++面试通关密码:这10个问题背后的秘密你知道吗?
以下是C++常见面试题及其解析,涵盖基础概念、面向对象、内存管理和高级特性等方面:
1. 指针和引用的区别
o 答案:
o 指针是一个变量,存储内存地址;引用是别名,绑定到某个对象。
o 指针可以为空(nullptr),引用必须初始化且不可为空。
o 指针可以重新指向其他对象,引用绑定后不可更改。
o 使用指针需要手动解引用(*),引用直接使用。
o 解析:
引用在底层通过指针实现,但语法更安全。函数参数传递时,引用可避免拷贝且无需检查空指针。
2. 虚函数(Virtual Function)与多态
o 答案:
虚函数通过虚函数表(vtable)实现动态多态。基类声明virtual的函数,派生类可覆盖(override)。运行时根据对象实际类型调用正确函数。
o 解析:
o 虚函数表是编译器为每个含虚函数的类生成的函数指针数组。
o 对象内存布局包含指向虚表的指针(vptr)。
o override关键字(C++11)明确表示覆盖基类虚函数,避免拼写错误导致的隐藏(hide)。
3. new和malloc的区别
o 答案:
o new是运算符,malloc是库函数。
o new调用构造函数,malloc仅分配内存。
o new返回类型指针,malloc返回void*需强制转换。
o new失败抛出异常,malloc返回NULL。
o 解析:
优先使用new(类型安全),C++中new可重载,malloc不可。
4. 智能指针(Smart Pointers)
o 答案:
o unique_ptr:独占所有权,不可拷贝,可移动(std::move)。
o shared_ptr:引用计数,多个指针共享对象。
o weak_ptr:解决shared_ptr循环引用问题,不增加引用计数。
o 解析:
5. 堆(Heap)和栈(Stack)的区别
o 答案:
o 栈:由编译器管理,存储局部变量、函数参数,分配速度快,内存连续。
o 堆:手动管理(new/malloc),内存动态分配,可能产生碎片。
o 生命周期:栈变量随作用域结束销毁;堆对象需显式释放。
o 解析:
栈大小有限(默认几MB),堆受系统内存限制。
6. 虚析构函数的作用
o 答案:
基类析构函数声明为虚函数(virtual ~Base(){}),确保通过基类指针删除派生类对象时,调用完整的析构链。
o 解析:
若基类析构非虚,删除派生类对象时仅调用基类析构函数,导致内存泄漏。
7. const关键字的用法
o 答案:
o 修饰变量:值不可变(const int x = 5;)。
o 修饰指针:const int* p(指向常量)或int* const p(指针不可变)。
o 成员函数:void func() const,表示不修改成员变量。
o 解析:
const提高代码安全性,编译器强制检查。
8. STL中vector和list的区别
o 答案:
o vector:动态数组,连续内存,支持随机访问(O(1)),插入/删除尾部高效(O(1)),中间操作O(n)。
o list:双向链表,非连续内存,插入/删除任意位置O(1),随机访问O(n)。
o 解析:
频繁插入/删除选择list,需要快速访问选择vector。
9. 单例模式(Singleton)实现
o 答案(C++11线程安全版):
o 解析:
通过删除拷贝构造函数和赋值运算符确保唯一性,局部静态变量实现懒加载。
10. 移动语义(Move Semantics)
o 答案:
C++11引入移动语义,通过右值引用(&&)转移资源所有权,避免深拷贝。
示例:
o 解析:
std::move将左值转换为右值,触发移动操作。
总结
掌握上述问题需理解C++核心机制(如内存管理、多态、RAII)和现代特性(如智能指针、移动语义)。面试时结合代码示例和实际项目经验,展示对底层原理和工程实践的理解。
注:文章仅供参考,不作为任何依据使用。如您有任何问题请站内私信。