C++八股文(编译与链接)
1. 头文件和源文件如何组织?
头文件 (.h/.hpp) 的职责:
- 类的声明
- 函数原型
- 常量定义
- 模板定义
- 内联函数定义
源文件 (.cpp/.cc) 的职责:
- 函数的具体实现
- 类成员函数的实现
- 全局变量的定义
- 静态变量的定义
组织原则:
- 一个类对应一对 .h 和 .cpp 文件
- 头文件使用 include guard 或
#pragma once防止重复包含 - 头文件只放声明,源文件放实现
- 能用前置声明就不要 include 完整头文件
- 修改源文件不会触发依赖该头文件的其他文件重新编译
2. #define 和 const 有什么区别?
处理阶段:
#define在预处理阶段进行文本替换,编译器看不到宏名const在编译阶段处理,有类型检查
类型安全:
#define没有类型,只是文本替换const有明确类型,编译器会进行类型检查
作用域:
#define没有作用域概念,定义后全局生效const有作用域限制,可以是局部或全局
调试:
#define调试时只能看到替换后的值const调试器可以显示变量名和值
内存:
#define不占用内存空间const占用内存空间(可能被编译器优化)
3. inline 函数和宏有什么区别?
宏的特点:
- 简单的文本替换,没有语法检查
- 容易产生副作用,如
#define SQUARE(x) x*x调用SQUARE(a+1)会展开为a+1*a+1 - 没有类型检查
- 无法调试,不能设置断点
- 不遵守作用域规则
inline 函数的特点:
- 真正的函数,有完整的类型检查
- 不会有宏的副作用问题
- 可以设置断点调试
- 遵守作用域和访问控制规则
- 可以作为类成员函数
- inline 只是建议,编译器决定是否真正内联
性能:
- 两者都旨在减少函数调用开销
- 复杂函数即使声明 inline 也可能不会内联
- 现代编译器会自动优化,不必过度使用 inline
4. 如何使用命名空间避免名称冲突?
命名空间的作用:
- 组织代码,将相关功能逻辑分组
- 避免全局命名空间污染
- 解决不同库之间的同名问题
- 提供代码的逻辑层次结构
使用方式:
- 完全限定名:
std::vector<int> v;明确指定命名空间 - using 声明:
using std::cout;引入特定名称 - using 指令:
using namespace std;引入整个命名空间 - 嵌套命名空间:
namespace company::project::module创建层次结构 - 匿名命名空间: 限制符号在当前文件内可见,替代 static
注意事项:
- 头文件中避免
using namespace,防止污染包含该头文件的代码 - 源文件中可以适度使用 using 声明
- 为项目创建独特的命名空间,避免与标准库或第三方库冲突
5. 静态链接与动态链接有何区别?
静态链接:
- 编译时将库代码复制到可执行文件中
- 可执行文件体积大,但独立运行
- 不依赖外部库文件,部署简单
- 库更新需要重新编译整个程序
- 多个程序使用同一库会占用更多磁盘和内存
动态链接:
- 运行时加载共享库(.dll/.so)
- 可执行文件体积小
- 多个程序共享库代码,节省内存和磁盘空间
- 库更新后无需重新编译程序
- 需要确保运行环境有正确版本的库
选择依据:
- 独立部署、避免依赖问题:静态链接
- 节省空间、方便更新:动态链接
- 性能敏感场景:静态链接略快
- 插件系统、模块化设计:动态链接
6. 如何调试链接错误
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
C++八股文全集 文章被收录于专栏
本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。
查看29道真题和解析