C++八股文(面向对象编程2)
1. C++ 中如何使用析构函数进行资源释放?
- RAII原则:资源获取即初始化,构造函数获取资源,析构函数释放资源。对象生命周期结束时自动释放
- 释放内容:动态分配的内存(delete/delete[])、文件句柄(fclose)、网络连接、互斥锁、数据库连接等
- 调用时机:栈对象离开作用域、delete堆对象、程序结束时全局对象销毁
- 异常安全:析构函数不应抛出异常,用try-catch捕获并处理
- 虚析构函数:多态基类的析构函数必须是虚函数,确保通过基类指针删除派生类对象时正确释放资源
- 智能指针:现代C++推荐用unique_ptr、shared_ptr自动管理资源,避免手动delete
- 最佳实践:一个类管理一种资源,遵循单一职责原则
2. 如何实现 C++ 中的单例模式(Singleton)?
懒汉式(线程安全,C++11):
class Singleton {
private:
Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
static Singleton& getInstance() {
static Singleton instance; // C++11保证线程安全
return instance;
}
};
- Meyers单例:上面的方法,利用C++11静态局部变量初始化的线程安全性
- 饿汉式:程序启动时就创建实例,线程安全但可能浪费资源
- 双重检查锁定:C++11前的方案,现在不推荐,复杂且容易出错
- 关键点:①私有构造函数 ②删除拷贝构造和赋值运算符 ③静态获取实例方法 ④线程安全
- 优点:全局唯一实例、延迟初始化、线程安全
- 缺点:违反单一职责、难以测试、隐藏依赖关系
- 使用场景:配置管理、日志系统、线程池、数据库连接池
3. C++ 中如何实现接口?
- 纯虚函数接口:所有成员函数都是纯虚函数的抽象类
class IShape {
public:
virtual ~IShape() = default;
virtual double area() const = 0;
virtual void draw() const = 0;
};
- 命名约定:接口类名通常以I开头(IShape、ILogger)
- 析构函数:应该是虚函数,可以有默认实现
- 实现接口:派生类必须实现所有纯虚函数
- 多接口实现:通过多重继承实现多个接口
- 与Java/C#区别:C++没有interface关键字,用纯虚函数类模拟;可以有数据成员(但不推荐)
- 最佳实践:接口应该小而专注,遵循接口隔离原则;不要在接口中放数据成员
- 现代方案:C++20的concepts提供了更灵活的接口定义方式
4. C++ 中的拷贝构造函数是什么?
- 定义:参数是同类型对象的const引用的构造函数,
MyClass(const MyClass& other) - 调用时机:①用对象初始化另一对象 ②对象作为函数参数按值传递 ③函数按值返回对象(可能被优化掉)
- 默认行为:编译器生成的默认版本执行浅拷贝(逐成员复制)
- 何时自定义:类中有指针成员、动态资源、需要深拷贝时
- 实现要点:分配新资源、复制内容、处理异常
- 参数必须是引用:否则会无限递归(传参需要拷贝,拷贝又需要传参)
- const引用:允许从临时对象和const对象拷贝
- 移动语义:C++11引入移动构造函数,避免不必要的拷贝
5. C++ 中的赋值运算符重载如何实现?
class MyClass {
public:
MyClass& operator=(const MyClass& other) {
if (this != &other) { // 1. 检查自赋值
delete[] data; // 2. 释放旧资源
data = new int[other.size]; // 3. 分配新资源
size = other.size;
std::copy(o
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
C++八股文全集 文章被收录于专栏
本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。
查看12道真题和解析