🔹 #pragma once
基础
- 作用:防止头文件被多次包含(Multiple Inclusion),避免重复定义错误。
- 使用场景:通常放在 头文件(.h/.hpp)开头。
- 语法:
#pragma once
1. 与传统 include guard 对比
传统 include guard
#ifndef MYHEADER_H
#define MYHEADER_H
// 头文件内容
#endif // MYHEADER_H
使用 #pragma once
#pragma once
// 头文件内容
#pragma once
更简洁,不需要定义宏名- 编译器自动确保文件只被包含一次
2. 使用示例
假设有两个头文件 A.h
和 B.h
:
A.h
#pragma once
#include "B.h"
void funcA();
B.h
#pragma once
void funcB();
main.cpp
#include "A.h"
#include "B.h" // 即使这里再次包含 B.h,也不会重复编译
int main() {
funcA();
funcB();
return 0;
}
✅ 编译器只会处理一次 B.h
,避免重复定义。
3. 工作原理(原理简述)
- 编译器在预处理阶段,记录已经处理过的文件路径
- 如果同一文件再次被包含,则直接忽略
- 比宏方式更高效,因为不需要预处理器多次展开宏检查
4. 优缺点
优点
- 简单明了,减少宏定义错误
- 避免宏命名冲突
- 编译速度通常比传统 include guard 更快(现代编译器)
缺点
- 非标准:不是 C/C++ 标准的一部分,但大多数现代编译器都支持(GCC、Clang、MSVC)
- 路径依赖:如果同一文件通过不同路径包含,可能失效
- 跨编译器兼容性:老旧编译器可能不支持
5. 注意事项
- 放在头文件最顶部,确保生效
- 不要与宏 include guard 冲突,可以同时使用(兼容老编译器):
#pragma once
#ifndef MYHEADER_H
#define MYHEADER_H
// 内容
#endif
- 尽量避免通过 不同相对/绝对路径重复包含同一文件
✅ 总结
特性 | #pragma once | include guard |
---|---|---|
写法 | 简单,一行 | 需要宏定义 |
可读性 | 高 | 中 |
编译效率 | 高(现代编译器) | 略低 |
标准化 | 非标准,但广泛支持 | 标准 C/C++ |
跨路径重复包含 | 可能有问题 | 完全可靠 |
💡 小技巧:
- 对新项目推荐
#pragma once
,简洁高效 - 对需要兼容老编译器的项目,可以 pragma + include guard 双保险
发表回复