c++中如何防止头文件重复包含_c++ #ifndef与#pragma once区别【实例】
技术百科
裘德小鎮的故事
发布时间:2026-01-22
浏览: 次 应优先使用 #ifndef / #define / #endif,因其是标准、可移植、可靠;#pragma once 虽简洁但非标准,存在文件系统依赖和兼容性风险。
用 #ifndef 或 #pragma once 都能防止头文件重复包含,但它们机制不同、兼容性不同、行为边界也不同——选错可能在跨平台或大型项目中埋坑。
为什么重复包含头文件会出问题
多次包含同一头文件,会导致符号重定义(比如类重复声明、函数重复声明)、模板实例化冲突、编译变慢。C++ 标准不保证头文件被多次包含时的行为安全,必须主动防护。
常见触发场景:
- 多个头文件都
#include "common.h",而它们又被同一个.cpp同时包含 - 继承链中间接包含同一头文件(
A.h → B.h → C.h,同时A.h → C.)
h
#ifndef / #define / #endif 是标准、可控、可移植的方案
它依赖宏名唯一性,由预处理器在文本层面判断是否跳过内容。只要宏名不冲突,就可靠。
典型写法(注意命名规范):
#ifndef MYLIB_VECTOR_H_ #define MYLIB_VECTOR_H_include
namespace mylib { template
class vector { / ... / }; } // namespace mylib endif // MYLIB_VECTORH
关键点:
- 宏名建议用
大写 + 下划线 + 文件路径信息(如UTILS_LOG_H_),避免和用户代码/第三方库冲突 - 必须成对出现:
#ifndef和#endif之间不能有未配对的条件编译指令 - 支持所有符合标准的预处理器(GCC、Clang、MSVC、ICC 等),无兼容性风险
- 即使头文件被
#include <...>和#include "..."同时引用,也能正确识别为同一文件(靠路径字符串匹配)
#pragma once 是编译器扩展,简洁但有隐含限制
它让编译器直接按物理文件路径做去重,不依赖宏名,写起来更轻量:
#pragma onceinclude
namespace mylib { template
class vector { / ... / }; }
但它的问题藏在细节里:
- 不是 C++ 标准特性,虽被 GCC/Clang/MSVC 广泛支持,但某些嵌入式工具链或老版本编译器(如早期 TI C++ 编译器)可能不识别
- 对硬链接、符号链接、网络文件系统(NFS)、生成头文件(如通过 CMake configure_file 生成)等场景识别不稳定——同一逻辑头文件若路径不同,
#pragma once可能认为是两个文件 - 无法处理“不同路径指向同一文件”的情况(例如
/src/a.h和/build/src/a.h是硬链接),而#ifndef因宏名相同仍能生效 - 宏名冲突的风险被规避了,但换来的是对文件系统语义的强依赖
实际项目中怎么选
没有绝对优劣,只有上下文适配:
- 开源库、跨平台 SDK、需长期维护的底层模块:优先用
#ifndef,确保可预测性和最大兼容性 - 公司内部 MSVC/Clang 主导的项目,且构建环境统一、无符号链接/NFS:可用
#pragma once提高可读性,但需在 CI 中验证所有目标平台 - 混合使用?不推荐。同一项目中混用会让新人困惑,且 IDE 的头文件导航、静态分析工具可能表现不一致
- 现代建议:用
#pragma once+ 保留#ifndef注释作为兜底(非强制,仅提醒),但不要真写两套防护
真正容易被忽略的是:头文件防护只是第一道防线;如果头文件本身有定义非内联函数、全局变量或模板以外的实体,还需配合 inline、static、extern 或定义分离(声明放头文件,定义放 .cpp)来避免 ODR 违规——防护宏管不了链接期错误。
# 的是
# 能在
# 多个
# 都能
# 也能
# 会让
# 下划线
# 能有
# 工具
# c++
# 区别
# 字符串
# 为什么
# Static
# define
# 头文件
# 继承
# extern
# 处理器
# 文件系统
# 全局变量
# include
# ide
# 预处理器
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Python邮件系统自动化教程_批量发送解析与模板
- Windows怎样拦截QQ浏览器广告_Window
- Win11怎么设置鼠标宏_Win11鼠标按键自定义
- MAC如何安装Git版本控制工具_MAC开发环境配
- MySQL 中使用 IF 和 CASE 实现查询字
- Win11如何隐藏桌面图标 Win11一键隐藏/显
- 如何使用Golang实现文件追加操作_向已有文件追
- Go 中实现 Python urllib.quot
- Windows电脑键盘突然失灵怎么办?(驱动与硬件
- Win10怎么卸载剪映_Win10彻底卸载剪映方法
- Drupal 中 HTML 链接被双重转义导致渲染
- Windows蓝屏错误0x00000023怎么修复
- 如何在Golang中编写异步函数测试_Golang
- Mac的“预览”如何合并多个PDF_Mac文件处理
- php485在php5.6下能用吗_php485旧
- LINUX的SELinux是什么_详解LINUX强
- windows如何修改文件默认打开方式_windo
- VSC里PHP变量未定义报错怎么解决_错误抑制技巧
- Win10如何卸载自带Edge_Win10彻底卸载
- Windows7如何安装系统镜像_Windows7
- 为什么Go建议使用error接口作为错误返回_Go
- c# Task.Yield 的作用是什么 它和Ta
- Win11如何设置系统语言_Win11系统语言切换
- 如何在Golang中验证模块完整性_Golangg
- Win11如何连接Xbox手柄 Win11蓝牙连接
- Win11怎么把图标拖到任务栏_Win11固定应用
- PHP cURL GET请求:正确设置请求头与身份
- 如何使用Golang实现聊天室消息存档_存储聊天记
- Win10怎样卸载TeamViewer_Win10
- 如何解决同一段404代码在不同主机上表现不一致的问
- PHP主流架构怎么部署到Docker_容器化流程【
- Windows10电脑怎么连接蓝牙设备_Win10
- LINUX如何查看文件类型_Linux中file命
- php中常量能用::访问吗_类常量与作用域操作符使
- c++ atoi和atof函数用法_c++字符数组
- Python面向对象实战讲解_类与设计模式深入理解
- Windows电脑如何截屏?(四种快捷方法)
- Win11如何更改用户账户文件夹名称 Win11修
- VSC怎样在Linux运行PHP_Ubuntu系统
- 如何使用Golang实现基本类型比较_Golang
- Windows怎样关闭开始菜单推荐广告_Windo
- 如何在Golang中使用log包输出不同级别日志_
- 如何在Golang中使用内置函数_Golangle
- 如何在 Django 中修改用户密码后保持会话不丢
- Windows 11如何查看系统激活密钥_Wind
- Win11怎么查看wifi信号强度_检测Windo
- php查询数据怎么导出csv_查询结果转csv文件
- VSC怎么创建PHP项目_从零开始搭建项目的步骤【
- Golang如何遍历目录文件_Golang fil
- Windows10电脑怎么设置自动连接WiFi_W


QQ客服