C++八股文【详细总结】

1. C++中的多态性是如何实现的?

多态性允许使用基类指针或引用调用派生类的函数。在C++中,这主要通过虚函数机制实现。当基类声明虚函数时,派生类可以重写这些函数。编译器会为每个包含虚函数的类生成虚函数表(vtable),对象则包含指向该表的指针。运行时根据对象实际类型调用正确的函数实现。

cpp 复制代码
class Base {
public:
    virtual void show() { cout << "Base\n"; }
};
class Derived : public Base {
public:
    void show() override { cout << "Derived\n"; }
};

2. 智能指针的种类及其区别?

智能指针用于自动化内存管理,主要分为三类:

  • unique_ptr:独占所有权,不可复制但可移动
  • shared_ptr:通过引用计数实现共享所有权
  • weak_ptr:配合shared_ptr使用,不增加引用计数
cpp 复制代码
auto ptr1 = make_unique<int>(10); // 独占
auto ptr2 = make_shared<int>(20); // 共享
weak_ptr<int> ptr3 = ptr2; // 观察

3. 左值和右值的根本区别?

左值(lvalue)表示有持久存储位置的表达式,右值(rvalue)通常是临时对象或字面量。关键区别在于:

  • 左值可被赋值和取地址
  • 右值只能出现在赋值右侧
  • C++11引入右值引用(&&)实现移动语义

4. 移动语义解决了什么问题?

移动语义通过转移资源所有权而非深拷贝来优化性能。典型场景:

  • 避免大型对象拷贝开销
  • 实现高效容器操作
  • 使用std::move显式转换左值为右值
cpp 复制代码
vector<string> v;
string s = "data";
v.push_back(std::move(s)); // s资源转移后为空

5. const关键字的不同用法?

const的多场景应用:

  • 常量变量:const int MAX = 100;
  • 常量指针:const char* p(内容不可变)
  • 指针常量:char* const p(指针不可变)
  • 成员函数:void func() const(不修改对象状态)
  • 函数参数:避免意外修改

6. 虚函数表的工作机制?

虚函数表(vtable)是实现动态绑定的核心机制:

  1. 每个多态类拥有自己的vtable
  2. vtable存储虚函数地址
  3. 对象内含vptr指向其vtable
  4. 调用虚函数时通过vptr间接寻址

7. 模板元编程的应用场景?

模板元编程(TMP)在编译期执行计算:

  • 类型萃取(如std::is_integral
  • 编译期常量计算
  • 条件编译优化
  • 生成高效专用代码
cpp 复制代码
template<int N>
struct Factorial {
    static const int value = N * Factorial<N-1>::value;
};
template<> 
struct Factorial<0> { static const int value = 1; };

8. RAII原则的核心思想?

资源获取即初始化(RAII)是C++核心范式:

  • 构造函数获取资源
  • 析构函数释放资源
  • 确保异常安全
  • 智能指针是典型实现

9. STL容器的时间复杂度?

常见容器操作复杂度:

  • vector:随机访问O(1),插入删除O(n)
  • list:插入删除O(1),访问O(n)
  • map(红黑树):操作O(\\log n)
  • unordered_map:平均O(1),最坏O(n)

10. 如何避免内存泄漏?

关键防御措施:

  • 优先使用智能指针
  • RAII管理资源
  • 避免原始指针所有权模糊
  • 使用内存检测工具(Valgrind)

11. 完美转发的实现机制?

std::forward保持参数原始值类别:

  • 配合模板参数T&&使用
  • 转发左值/右值属性
  • 实现通用引用
cpp 复制代码
template<typename T>
void wrapper(T&& arg) {
    target(std::forward<T>(arg));
}

12. 异常安全保证等级?

四个标准等级:

  1. 基本保证:不泄露资源,对象保持有效
  2. 强保证:操作完全成功或回滚
  3. 不抛保证:承诺不抛出异常
  4. 无保证:可能遗留非法状态

13. 类型推导规则(auto/decltype)?

类型推导机制:

  • auto:模板类型推导规则
  • decltype:返回表达式声明类型
  • decltype(auto):保持值类别
cpp 复制代码
auto x = 10; // int
decltype(x) y = 20; // int
decltype(auto) z = y; // int&

14. 菱形继承问题解决方案?

虚继承解决多重继承路径:

cpp 复制代码
class A {};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {}; // 仅一份A实例

虚基类由最派生类直接构造

15. lambda表达式的实现本质?

Lambda是匿名函数对象:

  • 编译器生成唯一类
  • 捕获变量变为成员
  • operator()实现函数体
  • 捕获方式:[=]值捕获,[&]引用捕获

16. 并发编程的三大问题?

核心挑战:

  1. 竞态条件:未同步数据访问
  2. 死锁:相互等待资源
  3. 活锁:不断尝试但无法进展 解决方案:互斥锁、原子操作、条件变量

17. 静态断言的使用场景?

static_assert编译期断言:

  • 验证模板参数
  • 检查类型特性
  • 确保平台兼容性
cpp 复制代码
static_assert(sizeof(int)==4, "int must be 4 bytes");

18. 如何实现线程安全容器?

设计要点:

  • 细粒度锁(每个桶独立锁)
  • 无锁数据结构(CAS操作)
  • 写时复制(COW)
  • 接口设计避免竞争

19. 三/五/零法则?

特殊成员函数管理规则:

  • 三法则:需要自定义析构、拷贝构造、拷贝赋值
  • 五法则:增加移动构造、移动赋值
  • 零法则:依赖编译器默认实现

20. CRTP模式的应用?

奇异递归模板模式:

cpp 复制代码
template <typename T>
class Base {
public:
    void interface() {
        static_cast<T*>(this)->implementation();
    }
};
class Derived : public Base<Derived> {
    void implementation() { /*...*/ }
};

用于静态多态、代码复用

21. 指针与引用的本质区别?

核心差异:

  • 引用必须初始化且不可重绑定
  • 指针可为空,支持多级间接
  • 引用无独立存储空间
  • sizeof引用返回目标大小

22. 纯虚函数的作用?

抽象类定义规范:

  • 声明virtual void func() = 0;
  • 强制派生类实现
  • 不能实例化抽象类
  • 可包含非虚成员函数

23. 前置声明适用场景?

减少编译依赖:

  • 声明类/结构体:class MyClass;
  • 可用于指针/引用类型
  • 不能用于定义成员对象
  • 头文件中广泛使用

24. 位域的内存布局?

精确控制成员位宽:

cpp 复制代码
struct S {
    unsigned int a : 4; // 4位
    unsigned int : 2;   // 无名位域
    bool b : 1;
};

注意对齐规则和移植性问题

25. 类型擦除的实现技术?

隐藏具体类型:

  • void*+函数指针(C风格)
  • 继承+虚函数(多态)
  • std::function(函数对象)
  • std::any(C++17容器)

26. 协程的核心优势?

轻量级并发单元:

  • 用户态调度
  • 无上下文切换开销
  • 同步式异步编程
  • C++20标准支持
cpp 复制代码
generator<int> seq() {
    for(int i=0; ; ++i) co_yield i;
}

27. 如何优化虚函数调用?

性能优化手段:

  • final类/函数阻止重写
  • 编译器去虚拟化
  • 避免深度继承
  • 模板替代运行时多态

28. 结构化绑定用法?

解绑复合类型:

cpp 复制代码
std::pair<int, string> p{1, "test"};
auto [id, name] = p; // id=1, name="test"

支持数组、元组、自定义类型

29. 常量表达式上下文?

constexpr编译期计算:

  • 变量:常量初始化
  • 函数:可在编译时执行
  • if语句:编译期分支
  • C++20新增consteval

30. 内存对齐控制方法?

对齐控制:

  • alignas指定对齐值
  • alignof获取对齐要求
  • #pragma pack改变默认对齐
  • 影响内存访问效率
相关推荐
2401_891655812 小时前
此电脑网络位置异常的AD域排错指南的技术文章大纲
开发语言·python·算法
江公望2 小时前
C++11 std::function,10分钟讲清楚
开发语言·c++
leaves falling2 小时前
C++入门基础
开发语言·c++
huaweichenai2 小时前
java的数据类型介绍
java·开发语言
你真是饿了2 小时前
10.list
c++·list
tankeven2 小时前
HJ139 小红的01子序列计数(hard)
c++·算法
weixin_649555672 小时前
C语言程序设计第四版(何钦铭、颜晖)第十章函数与程序设计之汉诺塔问题
c语言·c++·算法
C羊驼2 小时前
C语言:随机数
c语言·开发语言·经验分享·笔记·算法
weisian1512 小时前
Java并发编程--17-阻塞队列BlockingQueue:生产者-消费者模式的最佳实践
java·阻塞队列·blockqueue