C++ 面试题通常涵盖基础知识、面向对象编程、内存管理、模板、STL(标准模板库)等方面。以下是一些常见的 C++ 面试题及其简要解答,供你参考:
1. C++ 基础知识
1.1 C++ 和 C 的区别是什么?
- C++ 是 C 的超集,支持面向对象编程(OOP)。
- C++ 引入了类、继承、多态、模板、异常处理等特性。
- C++ 支持函数重载和运算符重载,而 C 不支持。
- C++ 提供了标准模板库(STL),而 C 没有。
1.2 const
关键字的作用是什么?
- 用于定义常量,值不可修改。
- 修饰指针时:
const int* p
:指针指向的值不可修改。int* const p
:指针本身不可修改。const int* const p
:指针和指向的值都不可修改。
- 修饰成员函数时,表示该函数不会修改类的成员变量。
1.3 static
关键字的作用是什么?
- 在函数内部:使变量在函数调用之间保持其值。
- 在类中:
- 静态成员变量:类的所有对象共享该变量。
- 静态成员函数:只能访问静态成员变量,不能访问非静态成员。
1.4 inline
函数的作用是什么?
- 建议编译器将函数体直接插入调用处,以减少函数调用的开销。
- 适用于短小的函数。
2. 面向对象编程
2.1 什么是面向对象编程(OOP)?
- OOP 是一种编程范式,基于对象和类的概念。
- 四大特性:
- 封装:隐藏实现细节,提供接口。
- 继承:从基类派生出新类,复用代码。
- 多态:通过基类指针调用派生类的重写函数。
- 抽象:定义接口而不实现具体细节。
2.2 什么是虚函数?它的作用是什么?
- 虚函数是在基类中使用
virtual
关键字声明的函数。 - 允许派生类重写该函数,实现运行时多态。
- 通过基类指针或引用调用虚函数时,实际调用的是派生类的实现。
2.3 什么是纯虚函数和抽象类?
- 纯虚函数是在基类中声明但没有实现的虚函数,语法为
virtual void func() = 0;
。 - 包含纯虚函数的类称为抽象类,不能实例化。
- 派生类必须实现纯虚函数,否则派生类也是抽象类。
2.4 什么是多重继承?它有什么问题?
- 多重继承是指一个类可以从多个基类继承。
- 问题:
- 菱形继承问题:如果两个基类继承自同一个祖先类,会导致派生类中包含重复的祖先类成员。
- 解决方法:使用虚继承。
3. 内存管理
3.1 new
和 malloc
的区别是什么?
new
是 C++ 运算符,malloc
是 C 标准库函数。new
会调用构造函数,malloc
不会。new
返回具体类型的指针,malloc
返回void*
。new
可以重载,malloc
不能。
3.2 什么是内存泄漏?如何避免?
- 内存泄漏是指程序分配的内存未被释放,导致内存浪费。
- 避免方法:
- 使用智能指针(如
std::unique_ptr
、std::shared_ptr
)。 - 确保
new
和delete
成对使用。 - 使用 RAII(资源获取即初始化)原则。
- 使用智能指针(如
3.3 什么是智能指针?
- 智能指针是 C++11 引入的模板类,用于自动管理动态内存。
- 常见类型:
std::unique_ptr
:独占所有权,不能复制。std::shared_ptr
:共享所有权,使用引用计数。std::weak_ptr
:弱引用,不增加引用计数。
4. 模板
4.1 什么是模板?
- 模板是 C++ 的泛型编程工具,允许编写与类型无关的代码。
- 分为函数模板和类模板。
4.2 函数模板和类模板的区别是什么?
-
函数模板:用于定义通用函数。
cpptemplate <typename T> T add(T a, T b) { return a + b; }
-
类模板:用于定义通用类。
cpptemplate <typename T> class Box { private: T value; public: void setValue(T v) { value = v; } T getValue() const { return value; } };
4.3 什么是模板特化?
- 模板特化是为特定类型提供特殊的实现。
- 分为全特化和偏特化。
5. STL(标准模板库)
5.1 STL 的组成部分有哪些?
- 容器:如
vector
、list
、map
。 - 算法:如
sort
、find
。 - 迭代器:用于遍历容器。
- 函数对象:如
less
、greater
。 - 适配器:如
stack
、queue
。
5.2 vector
和 list
的区别是什么?
vector
:动态数组,支持随机访问,插入和删除效率较低。list
:双向链表,不支持随机访问,插入和删除效率较高。
5.3 map
和 unordered_map
的区别是什么?
map
:基于红黑树实现,键值对有序。unordered_map
:基于哈希表实现,键值对无序,查找效率更高。
6. 高级特性
6.1 什么是 RAII?
- RAII(资源获取即初始化)是一种编程技术,通过对象的生命周期管理资源。
- 资源在构造函数中获取,在析构函数中释放。
6.2 什么是移动语义和右值引用?
- 右值引用:
T&&
,用于绑定临时对象。 - 移动语义:通过移动构造函数和移动赋值运算符,避免不必要的拷贝。
6.3 什么是 Lambda 表达式?
-
Lambda 表达式是一种匿名函数,语法为:
cpp[capture](parameters) -> return_type { body }
-
示例:
cppauto add = [](int a, int b) { return a + b; }; std::cout << add(2, 3); // 输出 5
7. 编程题
7.1 实现一个单例模式
cpp
class Singleton {
private:
static Singleton* instance;
Singleton() {} // 私有构造函数
public:
static Singleton* getInstance() {
if (!instance) {
instance = new Singleton();
}
return instance;
}
};
Singleton* Singleton::instance = nullptr;
7.2 实现一个简单的智能指针
cpp
template <typename T>
class SimpleUniquePtr {
private:
T* ptr;
public:
SimpleUniquePtr(T* p = nullptr) : ptr(p) {}
~SimpleUniquePtr() { delete ptr; }
T* operator->() const { return ptr; }
T& operator*() const { return *ptr; }
// 禁止拷贝
SimpleUniquePtr(const SimpleUniquePtr&) = delete;
SimpleUniquePtr& operator=(const SimpleUniquePtr&) = delete;
};
总结
以上是一些常见的 C++ 面试题及其解答。在准备面试时,建议结合实际代码练习,深入理解每个概念和技术的应用场景。祝你面试顺利!