#ifndef vs #pragma once, 哪个更好用?

news2024/12/24 9:34:36

相关文章系列

预处理 #pragma 命令详解-CSDN博客

目录

1.引用

2.#pragma once

3.#ifndef

4.总结


1.引用

        在C++编程中,头文件守卫(Header Guard)是一种防止头文件内容在同一编译单元中被多次包含的技术。这种重复包含可能导致编译错误,如类型重定义或变量多重声明。为了解决这个问题,开发者通常使用预处理指令来确保头文件只被包含一次。最常见的两种方法是使用#ifndef/#define/#endif宏(也称为传统的头文件守卫)和#pragma once指令。

2.#pragma once

        #pragma once 是一个非标准但被广泛支持的预处理符号, 其主要作用是防止文件重复引入问题,它一般由编译器保证,同一文件不会被包含多次。这里的“同一文件”是指物理上的一个文件,而不是指内容相同的两个文件。这种方式比 #ifndef 更加简洁和直观,但是它不是标准的 C++ 语法,可能不被所有编译器支持,移植型差,有些编译器支持,有些编译器不支持,比如:gcc,vs 编译器支持,bcc 编译器不支持。使用 #pragma 的方式非常简单,只需要在头文件的开头添加一行 #pragma once 即可。例如:

#pragma once

3.#ifndef

        #ifndef 是一个标准的预处理指令,它使用条件编译的方式来防止头文件被重复包含。当编译器编译到 #ifndef 指令时,它会检查这个宏是否已经被定义,如果没有被定义,则编译该文件并定义该宏。如果已被定义,则跳过该文件的编译。这种方式比较通用,可以在所有的 C++ 编译器中使用,但是需要手动定义宏,稍微有些繁琐。#ifndef 是 C 语言相关的,通过宏定义避免文件多次编译。所以在所有支持C/C++ 语言的编译器上都是有效的。跨平台移植性好。使用 #ifndef 的方式需要定义一个宏,通常使用头文件的名称作为宏的名称。例如:

#ifndef _MY_TEST_H_
#define _MY_TEST_H_

// 头文件内容

#endif // _MY_TEST_H_

        在这个例子中,_MY_TEST_H_是一个宏,如果它没有被定义,则编译头文件并定义该宏。如果已经被定义,则跳过头文件的编译。

4.总结

        #pragma once 和 #ifndef 都是用于防止头文件被重复包含的预处理指令,但它们的实现方式略有不同。下面是它们的对比:

#pragma once 依赖于编译器,可移植性较差

#pragma once 是一个非标准的预处理指令,而 #ifndef 是一个标准的预处理指令。#ifndef…#define…#endif 是 C/C++ 标准中的一部分,支持 C/C++ 的编译器都能使用,可移植性更高。

使用 #pragma once 的代码简洁

#pragma once 更加简洁和直观,但是不是标准的 C++ 语法,可能不被所有编译器支持。#ifndef 是标准的 C++ 语法,可以在所有的编译器中使用,但是需要手动定义宏。

性能区别

使用 #ifndef,编译器每次看到 #include 这个文件都需要读入文件,解析代码,效率低
而使用 #pragma once 是编译器特有指令,根本不会重复打开文件, 可以直接在编译器内部进行文件的检查,大大提高效率。

        综合上述,在选择使用#ifndef/#define/#endif宏还是#pragma once时,应该考虑项目的具体需求和目标平台。如果你的项目需要在多种编译器上工作,特别是包括一些老旧或特定的编译器,那么传统的#ifndef守卫可能是更安全的选择。然而,如果你的项目主要针对现代编译器,并且你希望代码更简洁、易维护,那么#pragma once可能是一个更好的选择。

        无论选择哪种方法,重要的是保持一致性和清晰性。确保你的项目中所有头文件都使用相同的守卫方法,并且守卫的命名清晰明了,这样可以最大限度地减少混淆和错误的可能性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1606767.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搜维尔科技:【工业仿真】煤矿机械安全事故VR警示教育系统

产品概述 搜维尔科技 煤矿机械安全事故VR警示教育系统 系统内容: 系统采用虚拟现实技术模拟矿井井下机械安全技术及事故,展现井下常见机械伤害事故,表现伤害事故的隐患点,能够模拟事故发生和发展过程;营造井下灾害发…

C#基于SSE传递消息给Vue前端实现即时单向通讯

一、简述 通常前端调用后端的API,调用到了,等待执行完,拿到返回的数据,进行渲染,流程就完事了。如果想要即时怎么办?如果你想问什么场景非要即时通讯,那可就很多了,比如在线聊天、实…

HQL,SQL刷题,尚硅谷(中级)

目录 相关表结构: 1、order_info表 2、order_detail表 题目及思路解析: 第一题,查询各品类销售商品的种类数及销量最高的商品 第二题 查询用户的累计消费金额及VIP等级 第三题 查询首次下单后第二天连续下单的用户比率 总结归纳&#xff1a…

C#版Facefusion:让你的脸与世界融为一体!-02 获取人脸关键点

C#版Facefusion:让你的脸与世界融为一体!-02 获取人脸关键点 目录 说明 效果 模型信息 项目 代码 下载 说明 C#版Facefusion一共有如下5个步骤: 1、使用yoloface_8n.onnx进行人脸检测 2、使用2dfan4.onnx获取人脸关键点 3、使用arcfa…

【MATLAB源码-第36期】matlab基于BD,SVD,ZF,MMSE,MF,SLNR预编码的MIMO系统误码率分析。

操作环境: MATLAB 2022a 1、算法描述 1. MIMO (多输入多输出):这是一个无线通信系统中使用的技术,其中有多个发送和接收天线。通过同时发送和接收多个数据流,MIMO可以增加数据速率和系统容量,同时提高信号的可靠性。…

算法1: 素数个数统计

统计n以内的素数个数 素数:只能被1和自身整除的自然数,0和1除外; 举例: 输入:100 输出:25 import java.util.*; class Test1{public static void main(String[] args){int a 100; //输入数字//…

41、二叉树-二叉树的层序遍历

思路: 层序遍历就是从左到右依次遍历。这个时候就可以使用队列的方式。例如先把头节点入队,然后遍历开始,首先计算队列长度,第一层,长度为了,遍历一次,依次出队,头结点出队&#xff…

Redis的RedisObject和对外可见的5种数据结构

目录 RedisObject Redis的编码方式 对外可见的5种数据结构 1.string string结构的源码 为什么是小于44字节会采用embstr编码? embstr和raw区别 2.list list结构的源码 3.set set结构的源码 4.zset zset结构的源码 5.hash hash结构的源码 Redis中…

淘宝客订单产品设计:连接商家与推广者的智能桥梁

随着电商行业的迅速发展,淘宝客作为一种常见的推广方式,为商家引流、提升销量发挥了重要作用。而淘宝客订单产品的设计,则是连接商家与推广者的智能桥梁,本文将对其进行探讨与分析。 ### 1. 淘宝客订单产品的定义 淘宝客订单产品…

梯度提升树(Gradient Boosting Trees)

通过5个条件判定一件事情是否会发生,5个条件对这件事情是否发生的影响力不同,计算每个条件对这件事情发生的影响力多大,写一个梯度提升树(Gradient Boosting Trees)模型程序,最后打印5个条件分别的影响力。 示例一 梯…

【目标检测】Focal Loss

Focal Loss用来解决正负样本不平衡问题,并提升训练过程对困难样本的关注。 在一阶段目标检测算法中,以YOLO v3为例,计算置信度损失(图中第3、4项)时有目标的点少,无目标的点多,两者可能相差百倍…

WSL(Ubuntu)、PC物理机,linux开发板三个设备通讯,镜像模式

文章目录 一、前言二、使用2.1 需要的系统信息2.2 添加 .wslconfig 文件 三、如何从局域网访问WSL中的服务 一、前言 最近在使用Linux开发板的环境下,由于使用的 WSL的子系统,并不是虚拟机,导致 网络传输 这方面不是很方便,由于 W…

AGM AG32 MCU在汽车UWB应用方案

AG32的汽车UWB应用方案 汽车电子产品的日益成熟,包括ADAS和车载信息娱乐,正在推动对CPLD的需求。例如,利用安装在车上的各种传感器(如雷达、摄像头和激光雷达等)来感知周围环境,实现实时监测和数据处理。这…

docker容器技术篇:数据卷的常用操作

Docker数据卷的使用 在docker中,为了方便查看容器内产生的数据或者将多个容器中的数据实现共享,就涉及到容器数据卷管理,那什么是数据卷呢,往下看!!! 1 数据卷概念 数据卷是一个共给容器使用…

一款挺不错网站维护页面HTML源码

一款挺不错网站维护页面源码,单HTML不需要数据库,上传到你的虚拟机就可以用做维护页面还不错,用处多。。 源码下载 一款挺不错网站维护页面源码

C# - 反射动态添加/删除Attribute特性

API: TypeDescriptor.AddAttributes TypeDescriptor.GetAttributes 注意:TypeDescriptor.AddAttributes添加的特性需要使用 TypeDescriptor.GetAttributes获取 根据api可以看到,该接口不仅可以给指定类(Type)添加特性&#xf…

设计模式——模版模式21

模板方法模式在超类中定义了一个事务流程的框架, 允许子类在不修改结构的情况下重写其中一个或者多个特定步骤。下面以ggbond的校招礼盒发放为例。 设计模式,一定要敲代码理解 模版抽象 /*** author ggbond* date 2024年04月18日 17:32* 发送奖品*/ p…

华为框式交换机S12700E系列配置CSS集群

搭建集群环境 a.为两台交换机上电&#xff0c;按照数据规划分别对两台框式交换机进行配置 <HUAWEI> system-view [HUAWEI] sysname Switch1 [Switch1] set css id 1 [Switch1] set css priority 150 //框1的集群优先级配置为150 [Switch1] interface css-port 1 [Sw…

后端-MySQL-week11 多表查询

tips: distinct————紧跟“select”之后&#xff0c;用于去重 多表查询 概述 一对多&#xff08;多对一&#xff09; 多对多 一对一 多表查询概述 分类 连接查询 内连接 外连接 自连接 必须起别名&#xff01; 联合查询-union&#xff0c;union all 子查询 概念 分类 …

家庭营销广告Criteo公司首次获得MRC零售媒体测量认证

家庭营销广告Criteo公司首次获得零售媒体测量MRC认证 商业媒体公司Criteo2024年3月28日宣布&#xff0c;它首次获得媒体评级委员会&#xff08;MRC&#xff09;的认证&#xff0c;在其企业零售媒体平台commerce Max和commerce Yield上&#xff0c;在桌面、移动网络和移动应用内…