C++ 头文件优化

C++ 是一种灵活的语言,所以需要一种积极的方法来分析和减少编译时依赖。一种常见的达到这个目的的方法是,将依赖从头文件里转移到源代码文件里。实现这个目的的方法叫做提前声明。
简而言之,这些声明告诉编译器某个函数接受和返回哪些参数,而具体的定义则规定了具体的行为。让我们根据下面两种规则来改进编译时长并减少可移植性问题,并且使用 include-what-you-use 这种自动应用这些规则到你的代码库的工具。
1、提前声明类型以加速编译速度
为了改进编译时间,尽可能地用提前类型声明来代替#include 指令。例如:
#include <iostream> #include "a.hpp"
#include "b.hpp"class MyClass
{A a_; B* b_;public:B& foo(std::string arg);
};std::ostream& operator<<(std::ostream& out, const MyClass& obj);
编译器如果需要知道它的大小或者接口,那么只需要知道它的类型的定义。而对于B 来说则不是,任何类型的指针或者引用的大小都是一样的。所以这里的 include可以被提前声明替代。
编译器也不需要知道 std::string 和 std::ostream 的类型,因为它们是模板(可能带有其它未知的默认的模板类型参数),因此我们不能提前声明它们。幸运的是,头文件 为 std::ostream 提供了提前声明。即使std::ostream 的定义是需要的, 仅仅提供了它的定义,而没有输入流或者是 std::cin,std::cout 等等。
改进的文件仅需要以下 include 指令和提前声明:
#include <iosfwd>
#include "a.hpp"
class B;
</code></pre>
这可以让生成的文件小很多。
原则:尽可能使用类型提前声明,但是有外部类型的时候需要特别注意。
2、可移植性问题
如果头文件 A 包含了头文件 B,那么你在包含头文件 A 的时候也会获得 B 的定义。这可能会引起一些细微的关于标准库的问题。除了某些例外,并没有定义哪些头文件包含了哪些。
为了改进编译时间,当需要某些特性的声明时,很多编译器实现包含了一些私有头文件而不是超大的公有头文件。所以当你(意外地)依赖某些间接包含的头文件,你的代码可能因为没有包含某些头文件而无法在别的编译器上成功编译。
这也是前一个例子里讲到的:代码没有包含 string 头文件。在我的平台上这段代码依然可以编译,因为 stream 头文件隐式地包含了,但在别的平台则不一定。
原则:将你要用到的头文件包含进来。如果你需要一个声明,包含相应的头文件。即使最后你的代码里有重复的包含指令,多谢头文件guard 指令,这也没什么问题。
3、Include-what-you-use
好消息是你不用自己手动来执行这两条原则。有一个对应的工具,include-what-you-use(IWYU):https://include-what-you-use.org
这是一个 Google 开发的基于 clang 的工具,用于执行这两个原则:尽可能地将包含指令替换为提前声明,如果依赖简介包含则添加相应的包含指令。
从源代码编译或者从网上下载预编译二进制文件后,你可以轻松地将它与 make 或者 CMake 一起使用。如果使用 make,你只需要将 CXX 变量设置为 IWYU,如果是 CMake 则设置好 CMAKE_CXX_INCLUDE_WHAT_YOU_USE 选项。请查看它们的文档获取更多详细信息。你也可以手动执行,它接受跟 clang 一样的参数。
然后它会给你列出将会对每个文件做出的更改。例如根据我们之前举例的文件,它会得出如下结果:
header.hpp should add these lines:
#include // for string
class B;
header.hpp should remove these lines:
– #include “b.hpp” // lines 6-6
The full include-list for header.hpp:
#include // for ostream
#include // for string
#include “a.hpp” // for A
class B;
除此之外还有一个 python 脚本 fix_includes.py。如果你将 IWYU 的输出作为参数给它执行,它会将这些更改立即执行。
原则:偶尔将 IWYU 运行于你的代码。它会改进编译时间和解决可移植性问题。
4、30倍的超快编译加速是什么样的
提前声明只能提供有限的改进。现在越来越多的公司面临着在高峰时段增加计算能力的需求和更快地响应市场的压力。现在,我们可以在高峰时期进行繁重的编译任务,并且加速你的软件开发时间而不需要改变代码或者增添额外硬件。
通过将任务分布在网络中的本地机器或者是虚拟机上,并且无缝地运行,Incredibuild 的创新解决方案可以为耗时的任务进行加速,例如编译、测试和其它。
欢迎点击了解 Incredibuild 加速 C/C++ 构建编译的解决方案,并获取试用 License!
相关文章:
C++ 头文件优化
C 是一种灵活的语言,所以需要一种积极的方法来分析和减少编译时依赖。一种常见的达到这个目的的方法是,将依赖从头文件里转移到源代码文件里。实现这个目的的方法叫做提前声明。 简而言之,这些声明告诉编译器某个函数接受和返回哪些参数&…...
DataRockMan洛克先锋OZON选品工具
随着全球电子商务的飞速发展,跨境电商平台已成为越来越多企业和个人追逐市场红利的重要战场。在众多跨境电商平台中,OZON以其独特的市场定位和强大的用户基础,吸引了无数卖家的目光。然而,如何在OZON平台上成功选品,成…...
【MySQL精通之路】全文搜索(9)-全文解析器-MeCab
主博客: 【MySQL精通之路】全文搜索功能-CSDN博客 目录 1.介绍 2.安装MeCab Parser插件 3.创建使用MeCab分析器的FULLTEXT索引 4.MeCab Parser空间处理 5.MeCab分析程序停止字处理 6.MeCab Parser术语搜索 7.MeCab分析程序通配符搜索 8.MeCab语法分析器短语…...
【工具】 MyBatis Plus的SQL拦截器自动翻译替换“?“符号为真实数值
【工具】 MyBatis Plus的SQL拦截器自动翻译替换"?"符号为真实数值 使用MyBatis的配置如下所示: mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl调用接口,sql日志打印如下: 参数和sql语句不…...
RT-DETR:端到端的实时Transformer检测模型(目标检测+跟踪)
博主一直一来做的都是基于Transformer的目标检测领域,相较于基于卷积的目标检测方法,如YOLO等,其检测速度一直为人诟病。 终于,RT-DETR横空出世,在取得高精度的同时,检测速度也大幅提升。 那么RT-DETR是如…...
OrangePi Kunpeng Pro开发板初体验——家庭小型服务器
引言 在开源硬件的浪潮中,开发板作为创新的基石,正吸引着全球开发者的目光。它们不仅为技术爱好者提供了实验的平台,更为专业开发者带来了实现复杂项目的可能性。本文将深入剖析OrangePi Kunpeng Pro开发板,从开箱到实际应用&…...
AquaCrop农业水资源管理,模拟作物生长过程中水分的需求与消耗
AquaCrop是由世界粮食及农业组织(FAO)开发的一个先进模型,旨在研究和优化农作物的水分生产效率。这个模型在全球范围内被广泛应用于农业水管理,特别是在制定农作物灌溉计划和应对水资源限制方面显示出其强大的实用性。AquaCrop 不…...
爬虫之re数据清洗
文章目录 一、正则【Regular】二、重要语法1、获取内容: 左边(.*?)右边2、替换数据: re.sub(源数据|源数据, 目标数据, 字符串) 一、正则【Regular】 概念: 根据程序员的指示, 从<字符串>中提取数据 结果: 列表 使用频率: 正则跟xpath相比, 正则是弟弟 二、重要语法 …...
惯性动作捕捉与数字人实时交互/运营套装,对高校元宇宙实训室有何作用?
惯性动作捕捉与数字人实时交互/运营套装,可以打破时空限制,通过动捕设备写实数字人软件系统动捕设备系统定制化数字人短视频渲染平台,重塑课程教学方式,开展元宇宙沉浸式体验教学活动和参观交流活动。 写实数字人软件系统内置丰富…...
Leecode---栈---每日温度 / 最小栈及栈和队列的相互实现
栈:先入后出;队列:先入先出 一、每日温度 Leecode—739题目: 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温…...
Linux系统编程——动静态库
目录 一,关于动静态库 1.1 什么是库? 1.2 认识动静态库 1.3 动静态库特征 二,静态库 2.1 制作静态库 2.2 使用静态库 三,动态库 3.1 制作动态库 3.2 使用动态库一些问题 3.3 正确使用动态库三种方法 3.3.1 方法一&…...
json formatter哪个好用
在众多的JSON Formatter工具中,确实有几个相当出色的选择,它们各自拥有独特的特点和优势,可以满足不同用户群体的需求。下面就来为大家推荐几个好用的JSONFormatter工具: 1. JSON Formatter & Validator:这款工具…...
react的hooks是什么意思
React Hooks 是 React 16.8 版本引入的一个新特性,它允许你在不编写类组件的情况下使用状态和其他React特性。Hooks使得函数组件变得更加灵活和强大,因为你可以在其中添加状态逻辑、生命周期方法以及其他React功能。 在传统的React类组件中,…...
AVFrame相关接口(函数)
分配和释放 分配 AVFrame AVFrame *av_frame_alloc(void); 分配一个新的 AVFrame 并返回一个指向它的指针。返回的 AVFrame 需要手动释放。 释放 AVFrame void av_frame_free(AVFrame **frame); 释放由 av_frame_alloc 分配的 AVFrame。这个函数会释放帧的数据并将指针设为 …...
低代码与人工智能的深度融合:行业应用的广泛前景
引言 在当今快速变化的数字化时代,企业面临着越来越多的挑战和机遇。低代码平台和人工智能技术的兴起,为企业提供了新的解决方案,加速了应用开发和智能化转型的步伐。 低代码平台的基本概念及发展背景 低代码平台是一种软件开发方法&#x…...
嵌入式测试基础知识
1.白盒测试也称为结构测试,主要用于检测软件编码过程中的错误。 2.黑盒测试又称为功能测试,主要检测软件的每一个功能是否能够正常使用。 3.软件测试流程:根据测试需求编写测试计划、方案,测试用例,做测试分析&#…...
基于网关的ip频繁访问web限制
一、前言 外部ip对某一个web进行频繁访问,有可能是对web进行攻击,现在提供一种基于网关的ip频繁访问web限制策略,犹如带刀侍卫,审查异常身份人员。如发现异常或者暴力闯关者,即可进行识别管制。 二、基于网关的ip频繁访…...
GSM信令流程(附着、去附着、PDP激活、修改流程)
1、联合附着流程 附着包括身份认证、鉴权等 2、去附着流程 用户发起去附着 SGSN发起去附着 HLR发起去附着 GSSN使用S4发起去附着 3、Activation Procedures(PDP激活流程) 4、PDP更新或修改流程 5、Deactivate PDP Context 6、RAU(Routeing Area Update)流程 7、鉴权加…...
OAK相机如何将 YOLOv10 模型转换成 blob 格式?
编辑:OAK中国 首发:oakchina.cn 喜欢的话,请多多👍⭐️✍ 内容可能会不定期更新,官网内容都是最新的,请查看首发地址链接。 Hello,大家好,这里是OAK中国,我是Ashely。 专…...
【Python】解决Python报错:AttributeError: ‘class‘ object has no attribute ‘xxx‘
🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…...
3个步骤打造全方位网络电台体验:foobox-cn配置指南
3个步骤打造全方位网络电台体验:foobox-cn配置指南 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 在数字音乐时代,如何高效管理和收听网络电台成为音乐爱好者的核心诉求。网络…...
软件开发中的架构:概念、价值与常见模式
在软件工程实践中,“架构”是一个高频出现但又常被误解的术语。很多人将其等同于技术选型或框架选择,但实际上,软件架构远不止于此。它关乎系统的整体结构、组件之间的关系以及指导系统演进的核心原则。本文将系统性地解释什么是软件架构、为…...
Windows性能优化:任务管理器深度使用指南
Windows性能优化:任务管理器深度使用指南Windows系统运行缓慢、卡顿?系统自带的任务管理器是诊断和解决性能瓶颈的强大工具。本文将带你深度挖掘Windows任务管理器的各项功能,重点介绍如何利用它进行进程管理、性能监控、启动项优化等操作&am…...
智能求职工具GetJobs:让你的投递效率提升300%的全流程指南
智能求职工具GetJobs:让你的投递效率提升300%的全流程指南 【免费下载链接】get_jobs 💼【找工作最强助手】全平台自动投简历脚本:(boss、前程无忧、猎聘、拉勾、智联招聘) 项目地址: https://gitcode.com/gh_mirrors/ge/get_jobs 每天…...
10G以太网Subsystem避坑指南:复位敏感性与时钟配置的实战经验
10G以太网Subsystem避坑指南:复位敏感性与时钟配置的实战经验 在高速网络设备开发中,10G以太网Subsystem的稳定性直接决定了系统性能上限。经历过三次产品迭代后,我发现80%的链路故障都可追溯到复位时序和时钟配置问题——这两个看似基础的环…...
别再让运动模糊毁了你的检测!一文搞懂工业相机飞拍里的CMOS传感器与快门速度怎么配
工业相机飞拍实战:CMOS传感器与快门速度的黄金搭配法则 在一条每分钟处理300个瓶盖的高速灌装线上,质检员小王发现相机拍摄的字符总是出现拖影——这已经是本周第三次因图像模糊导致误检停线了。类似场景每天都在全球数以万计的自动化产线上演࿰…...
跨平台OCR新利器:PP-OCRv5模型转ONNX实战指南,轻松应对多语言识别挑战
1. 为什么需要跨平台OCR解决方案 在日常工作和生活中,我们经常会遇到需要处理多语言文档的场景。比如收到一份包含中文、英文和日文的合同,或者需要从产品包装上识别不同语言的说明文字。传统OCR方案往往需要针对不同语言训练多个模型,不仅部…...
i18n-node快速入门:10个简单步骤实现应用国际化 [特殊字符]
i18n-node快速入门:10个简单步骤实现应用国际化 🌍 【免费下载链接】i18n-node Lightweight simple translation module for node.js / express.js with dynamic json storage. Uses common __(...) syntax in app and templates. 项目地址: https://g…...
MOOTDX终极指南:Python通达信数据接口让量化分析变得简单高效
MOOTDX终极指南:Python通达信数据接口让量化分析变得简单高效 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 你是否曾为获取股票数据而烦恼?面对复杂的API接口和繁琐的数据…...
3分钟零基础入门:GPU加速MediaPipe TouchDesigner插件完整指南
3分钟零基础入门:GPU加速MediaPipe TouchDesigner插件完整指南 【免费下载链接】mediapipe-touchdesigner GPU Accelerated MediaPipe Plugin for TouchDesigner 项目地址: https://gitcode.com/gh_mirrors/me/mediapipe-touchdesigner 你是否曾想过在TouchD…...
