豆包整理

首先是基础,C++和C的区别,C是面向过程,C++是多范式,支持面向对象和泛型编程,还有类、继承、多态这些特性,异常处理和STL也是C++独有的。const关键字能修饰变量、引用和成员函数,分别让变量只读、引用指向的对象不能改,以及成员函数不能修改成员变量。static关键字在函数里是局部静态变量,能保持状态;在类里是所有对象共享的成员,静态成员函数不依赖对象;在文件作用域能让变量或函数只在当前文件可见。指针和引用的区别,引用是别名,必须初始化,绑定后不能改,不能为空;指针是存地址的变量,可以不初始化,能指向不同对象,也能为空。然后是面向对象,虚函数通过虚函数表和虚表指针实现多态,每个含虚函数的类有个虚函数表,对象里有指向虚函数表的指针。纯虚函数是后面加=0的函数,包含纯虚函数的类是抽象类,不能实例化,子类必须实现纯虚函数。虚继承是为了解决菱形继承问题,让派生类里基类只有一份拷贝。override关键字显式声明函数覆盖基类虚函数,final关键字能禁止类被继承或虚函数被重写。内存管理方面,new/delete是C++的运算符,会调用构造函数和析构函数,返回具体类型的指针;malloc/free是C库函数,只分配内存,返回void*指针,需要手动计算大小和转换类型。智能指针有unique_ptr、shared_ptr和weak_ptr,unique_ptr独占所有权,不能复制只能移动;shared_ptr通过引用计数共享所有权,要注意循环引用的问题;weak_ptr是shared_ptr的弱引用,不增加引用计数,用来解决循环引用。STL部分,vector是动态数组,底层是连续内存,空间不足时会扩容,通常是2倍,频繁扩容影响性能,reserve可以预分配空间。map基于红黑树实现,元素有序,操作复杂度是O(log n);unordered_map基于哈希表实现,元素无序,平均操作复杂度是O(1),但哈希冲突时性能会下降。迭代器失效的场景,vector插入或删除元素可能导致所有迭代器失效,map和unordered_map插入元素时迭代器通常不会失效,删除元素时只有被删除元素的迭代器失效。多线程方面,线程安全是指多个线程访问共享资源时不会出现数据竞争等问题。mutex是互斥锁,用来保护共享资源,lock_guard和unique_lock是RAII风格的锁管理工具,能自动释放锁。atomic是原子类型,对其操作是原子的,不需要加锁,性能更高。死锁的四个条件是互斥、请求保持、不可剥夺和环路等待,预防死锁的方法有按固定顺序获取锁、使用RAII管理锁、设置超时机制等。模板和泛型编程,SFINAE技术是指模板参数替换失败时不会报错,而是尝试其他重载,常用于类型检查。模板特化是为特定类型提供特殊的模板实现,全特化是指定所有模板参数,偏特化是指定部分模板参数。现代C++特性,lambda表达式是匿名函数,语法是捕获列表{函数体},捕获列表可以按值或按引用捕获外部变量。移动语义通过右值引用实现,能避免不必要的拷贝,提高性能,std::move可以将左值转换为右值。constexpr在C++11中只能用于简单函数,C++14后可以用于更复杂的函数,允许在编译期计算。常见的设计模式,单例模式确保一个类只有一个实例,通常用局部静态变量实现线程安全的单例。观察者模式定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。

常见问题

枚举和枚举类有什么区别

简单来说,枚举 (enum) 是 C++ 中的传统方式(不限定作用域),而 枚举类 (enum class) 是 C++11 引入的现代方式(限定作用域)。你可以把 enum 想象成“自由散漫”的旧工具,而 enum class 是“严谨、安全”的新工具。以下是它们的核心区别:

  1. 作用域 (Scope) —— 最显著的区别
    • enum (不限定作用域): 枚举成员的名字直接暴露在外部作用域。这意味着如果两个枚举有相同的成员名,程序会报错。
    • enum class (限定作用域): 成员名被封闭在类内部。必须通过 ClassName::Member 的方式访问。
     // 传统枚举
     enum TrafficLight { RED, GREEN };
     // enum Color { RED, BLUE }; // 错误!RED 已经定义过了
    
     // 枚举类
     enum class NewTrafficLight { RED, GREEN };
     enum class NewColor { RED, BLUE }; // 正确!它们在不同的“房间”里
    
  2. 隐式转换 (Type Safety)
    • enum: 枚举值可以自动(隐式)转换为整数(int)。这虽然方便,但容易导致逻辑漏洞(例如:把“红灯”和数字 0 混用)。
    • enum class: 严禁隐式转换。如果你想把枚举值当整数用,必须进行强制类型转换(如 static_cast(...))。
     TrafficLight light = RED;
     if (light == 0) { /* 这里的比较是合法的,但可能不符合本意 */ }
    
     NewTrafficLight newLight = NewTrafficLight::RED;
     // if (newLight == 0) { /* 编译报错!类型不安全 */ }
    
  3. 底层类型 (Underlying Type)
    • enum: 底层类型不固定,由编译器决定(通常是 int),且不支持前置声明(除非在现代 C++ 中指定了类型)。
    • enum class: 默认底层类型是 int,但你可以手动指定(如 char, uint32_t),这不仅能节省内存,还支持前置声明。
     enum class Status : char { // 指定只占用 1 字节
         OK = 0,
         ERROR = 1
     };
    

对比总结表

特性 enum (传统) enum class (现代)
访问方式 RED Color::RED
作用域污染 有 (容易命名冲突) 无 (各自独立)
类型安全 弱 (可隐式转为 int) 强 (不可隐式转换)
内存控制 编译器决定 可手动指定 (如 : char)
前置声明 不支持 (通常) 支持