服务端2月18日 17:27
C++ 智能指针怎么选?unique_ptr/shared_ptr/weak_ptr 使用场景对比C++ 提供三种智能指针,均位于 `<memory>` 头文件。`unique_ptr` 独占所有权,不可拷贝只能移动,开销接近裸指针,是默认首选。`shared_ptr` 共享所有权,内部维护引用计数,最后一个持有者销毁时释放资源,拷贝和赋值增加计数。`weak_ptr` 是 `shared_ptr` 的观察者,不增加引用计数,通过 `lock()` 获取临时 `shared_ptr` 访问对象,用于打破循环引用。`make_unique` 和 `make_shared` 在单次分配中同时构造对象和控制块(后者),比单独 new 更高效且异常安全。自定义删除器允许在析构时执行特定操作,...服务端2月18日 17:28
C++ 内存泄漏怎么避免?RAII/智能指针/检测工具实战指南C++ 程序的内存分为栈(自动管理,函数结束释放)、堆(手动 new/delete)、全局/静态区(程序生命周期)和常量区(只读)。堆内存需开发者显式申请和释放,是内存泄漏的重灾区。泄漏的常见原因:new 后忘记 delete、异常导致跳过 delete、指针被覆写丢失地址。检测工具中,Valgrind 在运行时插桩检查,AddressSanitizer(ASan)由编译器插桩,开销更小、报错更直接。现代 C++ 的核心防御手段是 RAII 原则:资源获取即初始化,将资源生命周期绑定到栈对象,析构时自动释放。智能指针是 RAII 的典型应用:`unique_ptr` 独占所有权离开作用域...服务端2月18日 17:29
C++ 模板特化和偏特化怎么用?全特化/偏特化/SFINAE 详解模板特化允许为特定类型提供与通用版本不同的实现。全特化指定所有模板参数,为某一具体类型提供完全定制版本,全特化后的模板不再有模板参数。偏特化仅适用于类模板和变量模板,对部分参数做约束,保留剩余参数的通用性。例如 `template<typename T> class A<T*>` 为所有指针类型提供统一实现,T 仍为参数。函数模板不支持偏特化,只能用重载或全特化替代。SFINAE(替换失败并非错误)是模板元编程的基础规则:在模板实参替换阶段,若某个候选的替换导致类型错误,该候选被静默剔除而非编译报错。`std::enable_if` 利用 SFINAE,通过条件编译控制模板是否参与重载决...服务端2月18日 17:30
C++ 移动语义和完美转发怎么用?std::move/forward 原理详解C++11 引入移动语义解决不必要的深拷贝问题。核心在于区分左值(可取地址、具名)和右值(临时、不可取地址)。右值引用 `T&&` 可绑定到右值,表示该对象资源可被"窃取"而非复制。移动构造函数和移动赋值运算符通过转移资源(如指针、文件句柄)而非复制,显著提升性能。`std::move` 本质是无条件转为右值引用的 static_cast,并不移动任何东西,只是让重载决议选择移动版本。完美转发指函数模板将参数以原始值类别(左值/右值)传递给另一函数,借助 `std::forward<T>` 实现。`T&&` 在模板推导中是万能引用:实参为左值时 T 推导为左值引用,实参为右值时 T 推导...服务端2月18日 17:30
C++ 多态怎么实现?vtable/vptr 与动态绑定原理详解C++ 多态分编译时和运行时两种。编译时多态通过函数重载和模板实现,编译器根据参数类型或模板实参在编译期确定调用目标,零运行开销。运行时多态依赖虚函数机制:每个含虚函数的类拥有一张虚函数表(vtable),存储各虚函数的入口地址;每个对象实例持有指向所属类 vtable 的虚指针(vptr)。调用虚函数时,通过 vptr 查 vtable 完成动态绑定,实现了根据实际对象类型调用对应版本。纯虚函数使类成为抽象类,强制子类必须实现。析构函数声明为虚函数可确保 delete 基类指针时正确调用派生类析构,避免资源泄漏。多重继承下对象可能包含多个 vptr,分别指向不同基类的 vtable。
...服务端2月18日 17:31
C++ 多线程怎么写?mutex/条件变量/atomic/future 详解C++11 起 <thread> <mutex> <condition_variable> <atomic> <future> 是并发编程的核心。std::thread 创建线程,必须 join() 或 detach(),否则析构时 terminate。共享数据用 std::mutex 保护,lock_guard 在作用域自动加解锁,unique_lock 支持手动加解锁和配合条件变量。condition_variable 解决生产者-消费者问题:wait 释放锁并阻塞,notify_one/all 唤醒等待线程,注意用谓词版本 wait(lock, pred) 防虚假唤醒。std::a...服务端2月18日 17:32
C++ STL 容器怎么选?vector/map/unordered_map 对比与算法STL 容器分四类。序列容器:vector 连续内存随机访问 O(1) 尾插 O(1) 中间插 O(n);deque 双端队列两端 O(1);list 双向链表任意位置 O(1) 但不支持随机访问。关联容器:map/set 基于红黑树有序 O(log n),map 存键值对 set 存键。无序容器:unordered_map/unordered_set 基于哈希表平均 O(1) 最坏 O(n)。容器适配器:stack(默认 deque)、queue(默认 deque)、priority_queue(默认 vector+堆算法)。常用算法:sort O(nlogn)、find O(n)、c...服务端2月18日 17:33
C++ 异常处理怎么用?try/catch/noexcept 与异常安全详解C++ 异常用 try/catch/throw 处理运行时错误。throw 抛出异常对象,catch 按类型匹配捕获,catch(...) 捕获所有异常。标准异常继承自 std::exception,分 logic_error(编程错误)和 runtime_error(运行时错误)两大分支。自定义异常继承 std::runtime_error 或 std::exception,重写 what() 返回错误信息。异常安全三个级别:基本保证(异常后对象仍有效)、强保证(异常后状态回滚)、不抛保证(noexcept)。RAII 是异常安全的基石——栈展开时局部对象的析构函数保证执行,智能指针和...服务端2月18日 17:35
C++11 到 C++20 新特性有哪些?面试高频考点速览C++ 每个版本都有高频考点。C++11 最重要:auto 类型推导、range-for 循环、lambda 表达式(捕获列表是重点)、智能指针三件套(unique_ptr 独占、shared_ptr 共享引用计数、weak_ptr 打破循环)、右值引用与移动语义(避免深拷贝)、nullptr 替代 NULL、constexpr 编译期计算。C++14 补充了泛型 lambda(参数用 auto)和 make_unique。C++17 重点:结构化绑定、if constexpr 编译期分支、optional/variant/any 三种可选类型、string_view 避免字符串拷贝。C...服务端2月18日 17:36
C++ 常用设计模式怎么实现?单例/工厂/观察者/策略C++ 设计模式面试常考的是单例、工厂、观察者和策略这四个。单例用 Meyer's Singleton(局部静态变量),线程安全且简洁。工厂模式分简单工厂和抽象工厂,核心是用虚函数延迟到子类决定创建哪种对象。观察者模式在事件系统中到处都是,注意生命周期管理。策略模式用组合替代继承,运行时切换算法。
## 追问
### 单例模式的线程安全怎么保证?
Meyer's Singleton(函数内 static 局部变量)C++11 起保证线程安全,编译器自动加锁。不要用双重检查锁定(DCLP),早期 C++ 下有指令重排问题,现代 C++ 直接用 `static` 就行。
### 抽象...