头文件不应该含有非inline函数或对象的定义

Allegro如何进行四层板板层设计 板层的设计 阅读详情
头文件不应该含有非inline函数或对象的定义。....但是符号常量定义以及inline函数定义是特殊的定义。符号常量和inline函数可以被定义多次。  
   
  1.符号常量:在程序编译期间,在可能的情况下,符号常量的值会代替该名字的出现,这个替代过程被称为常量折叠(constant   folding)。   ....尽管理想情况下,一个具有初始值的常量可以被包含在多个不同的文件中,但是常量折叠使其变得并不必需,甚至在可执行文件只要出现一次就行。  
   
  是因为有常量折叠,符号常量才能在头文件中定义?  
   
  2.inline函数:如果编译器在调用点上没有内联该函数,则编译器会为该函数生成一个定义放到可执行文件中,如果在多个文件中生成同一函数的定义,则会产生一个不必要的、过大的可执行文件。  

这里涉及到编译器对inline和constant的实现.最常见的实现是(例如VC6),inline和constant的定义必须存在于每一个调用它们的CPP文件中,而且编译器不会帮你检查在两个CPP文件中的同名inline和constant是否是具有同样的值,所以大家都将它们放在头文件中. 可以想象,很有可能编译器直接将它们当作宏来处理了.  
  对于constant,在编译期间(准确地讲,应该是在预处理的时候),编译器会将它所遇到的所有constant的名字用constant的值来替换, 所以,虽然在每个CPP文件中都有constant的定义,但实际上,在最后的可执行文件中,并没有constant的存在.  
  对于inline,一个函数是否为inline,最终决定权在编译器手中.假如你在头文件中定义了一个inline,而该inline却被编译器枪毙了, 那么,可怜的编译器就会在每个存在该inline定义的CPP文件中生成一个全局函数,而且为了不产生冲突,这些函数都具有独一无二的名字.这样,你的可执行文件中就会多了一大堆具有奇怪名字并干着同样事情的函数:)
1.是因为有常量折叠,符号常量才能在头文件中定义?  
        不是因为有常量折叠,符号常量可以在头文件中定义,而是因为符号常量在不同的cpp文件中互相并不可见(类似于static全局变量,只在所处的文件中可见),所以即使名字相同也不会产生重复定义。  
        一般情况,在程序编译期间,编译器会为符号常量生成一个常量表,并用其值替换该名字(是在编译期间而不是预处理阶段,并进行类型检查,这是与宏的区别),并不为其分配空间,此动作被称为常量折叠。  
        但如果对常量进行了寻址(比如为其定义引用,或指针取其地址),编译器还是会为其分配空间。但是只能定义const引用或指针,所以其常量性也不受影响。  
   
  2.是因为inline函数的不能展开造成了“产生一个不必要的、过大的可执行文件”?  
        是的,因为若内联不成功,编译器会在每个引用该内联函数的cpp文件中,生成一个该函数定义。但实际实现中,有的链接程序会进行优化,使其只存在一个定义。一般来说,最好保证需内联的函数的能成功内联。  

        另外,定义一个内联函数只是向编译器申请内联,并不能保证一定能成为内联函数。内联函数的定义必须放在头文件中,因为必须让引用该函数的cpp文件都能见到该函数的定义,才能进行正确展开。


讨论出在http://bbs.youkuaiyun.com/topics/90349781

YOLOv11涨点改进| TGRS 2026 顶刊| 注意力改进篇| 引入MSEA多尺度边缘感知注意力,助力红外小目标检测、遥感目标检测、工业缺陷检测、图像去雨雾任务高效涨点 🔥本文提出了一种基于MSEA多尺度边缘感知注意力的YOLOv11改进模型,通过增强网络对边缘、纹理和细粒度信息的感知能力,显著提升复杂背景下的目标检测性能。MSEA模块采用多尺度空洞卷积提取上下文特征,并通过边缘监督和注意力融合机制强化目标边界信息。实验表明该方法在小目标、边界模糊目标和复杂纹理目标检测任务中表现优异,尤其在遥感、工业缺陷和红外检测等场景具有显著优势。文章详细介绍了MSEA的结构原理、核心代码实现、模块配置方法以及三种YOLOv11改进方案. 阅读详情

相关推荐

拼多多/Temu反爬参数逆向踩坑记:从浏览器调试到补环境完整复盘

本文详细解析了拼多多/Temu反爬参数`anti_content`的逆向工程实战,从浏览器调试到补环境完整复盘。通过JavaScript逆向技术,拆解关键函数定位、反混淆算法还原及补环境技术应用,帮助开发者突破电商平台复杂反爬系统,提升数据采集效率。

weixin_33978722的博客 912

inline

inline函数 1. 实现在 .h 中,未标记inline 每一个包含该头文件的源文件都将得到一份关于该函数的定义,链接器会报函数重定义错误 2. 实现在 .h 中,且标记inline 每一个包含该头文件的源文件都将得到一份关于该函数的定义,但是链接器不会报错 3. 实现在 .c 中,未标记inline 该函数可以被连接到其他编译单元中 4. 实现在 .c 中,且标记inline 该函数对其他编译单元不可见(类似于static),其他源文件不能链接该函数库 当连接到该库的时候会出现 undefine

XFH1207的博客 246

告别手动输入!用Burp插件+ddddocr,5分钟搞定图片验证码自动识别

本文详细介绍了如何利用Burp插件和ddddocr开源库快速构建图片验证码自动识别系统,实现高效、零成本的验证码自动化解决方案。通过环境搭建、性能调优和Burp Suite深度集成,显著提升安全测试效率,特别适用于金融和电商系统的批量测试场景。

weixin_29099217的博客 200

C++学习:inline的函数或者成员函数一定要定义在头文件中

    看C++的教材的时候,一直记得书上说inline只是一个提示,编译器可能会拒绝将函数定义成内联的。今天犯了思维定式的错误:函数或成员函数加上inline的时候,其实现部分一定要写在头文件中,否则链接的时候将发生找不到引用的错误(GCC编译器在编译的时候还会给出警告)。       请看下面重犯这个错误的代码:// MyClass.h#ifndef _MY_CLASS_H_#defi

1148

7系列ZYNQ硬件调试:Vitis无法识别ARM DAP的排查与解决

本文详细分析了Xilinx 7系列ZYNQ芯片在Vitis开发环境中无法识别ARM DAP的常见问题及解决方案。从硬件设计检查(电源系统、时钟电路)、JTAG连接诊断到软件环境排查,提供了全面的调试指南。特别针对ARM DAP初始化失败的情况,给出了实用的排查步骤和预防措施,帮助开发者快速定位和解决类似问题。

weixin_33737134的博客 513

从“烧电路”到“软杀伤”:拆解高功率微波(HPM)让无人机失灵的三种物理效应

本文深度解析高功率微波(HPM)如何通过热效应、电磁效应和非线性效应三种物理机制使无人机失灵。从电子元件的热损伤到系统的电磁干扰,再到电路中的非线性破坏,HPM技术为反无人机系统提供了高效的非动能打击手段。文章还探讨了现代无人机的多层级防护策略与应对方案。

weixin_42531886的博客 252

为什么不要在头文件中写上函数定义?

为什么不要在头文件中写上函数定义? 在C++/C中,一般的函数与全局变量的申明都会放在.H文件中,而且会在相应的.C文件中对函数和变量进行定义.全局变量在头文件中前面要加上EXTERN,定义时则不用 如果你在.H文件中对函数或变量直接定义,这个头文件只被一个文件包含是不会出错的,但是一旦它被两个或更多的文件包含,则会报错.编译器会告诉你函数或变量重复定义! 你可能会说,我不是已经

我是guyue,guyue就是我O(∩_∩)O 9708

C#实战:如何用Chart控件打造专业级数据可视化报表(附完整代码)

本文详细介绍了如何使用C#的Chart控件创建专业级数据可视化报表,涵盖柱状图、饼图和雷达图等多种图表类型的高级定制与交互增强。通过完整的代码示例,展示了从环境配置到动态数据绑定的全流程,助力开发者提升企业级应用的数据可视化能力。

ipfs8storage的博客 418

为什么函数定义不放在头文件中

在头文件中,会被多个源文件包括,在编译阶段会出现重复定义的问题 特殊的是内联函数,C++ primer中推荐内联函数的定义写在头文件中。

何解然_K|user 1215

Java代码变更影响分析:从静态解析到动态调用图的实战全链路

本文介绍了Java代码提交影响分析的核心原理与实现方法。主要内容包括:1)静态分析技术,通过JavaParser解析AST构建调用图,记录类与方法间的调用关系;2)动态分析技术,使用ByteBuddy进行字节码增强,捕获运行时调用路径;3)JCCI工具实现,结合javalang、unidiff等技术分析代码改动影响,并将结果存储到SQLite数据库。文章提供了完整的代码示例,展示了从AST解析、动态调用跟踪到实际工具应用的完整技术栈,为代码变更影响分析提供了实用解决方案。

墨夶的博客 1251

特殊通信领域场景应用:基于Simulink的数字预失真(DPD)算法仿真建模示例

增益压缩:高功率输入时输出信号的增益下降。相位失真:输入信号的相位随功率变化而改变。带外干扰:非线性失真会引入额外的频谱分量,影响邻道信号。多项式模型:用多项式拟合功率放大器的非线性特性。查找表(LUT):通过离线训练生成预失真映射表。自适应算法:实时调整预失真参数以动态补偿失真。发送端:生成随机比特流并调制为射频信号。预失真模块:对输入信号进行预失真处理。功率放大器模块:模拟非线性失真。接收端:解调信号并评估误码率(BER)。

xiaoheshang_123的博客 272

inline函数必须在头文件中定义吗?

前不久在写代码的时候遇到一个link错误,代码的原型如下所示,基本就是定义了一个基类和派生类,在派生类的一个成员函数中用到了基类定义的一个内联函数。 // base.h class Base { protected: void fun(); }; // base.cpp #include "base.h" inline void Base::fun() {} // derive

Eric Z的程序人生 1万+

Harness Engineering:让Coding Agent真正落地生产

本文将带你系统性地了解如何让Coding Agent真正落地生产,核心是依托(全球领先的持续交付、云成本管理、 feature flagging、安全治理一体化平台),结合企业级AIDD(AI-Driven Development)的工程化实践,构建一套可信赖、可观测、可扩展、可治理的Coding Agent落地体系。核心概念与理论基础:什么是Coding Agent?它和普通的AI代码补全工具(比如GitHub Copilot)有什么区别?什么是Harness Engineering?

移动开发前沿的博客 454

C++基础:inline函数

1.inline 函数 1.1定义:inline 函数由 inline 关键字定义,引入 inline 函数的主要原因是用它替代 C 中复杂易错不易维护的宏函数。 1.2编译器对 inline 函数的处理办法 编译器在编译阶段完成对 inline 函数的处理,即对 inline 函数的调用替换为函数的本体。但 inline 关键字对编译器只是一种建议,编译器可以这样去做,也可以不去做。从逻辑上来说,编译器对 inline 函数的处理步骤一般如下: (1)将 inline 函数体复制到inline..

weixin_58368590的博客 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

函数头文件_头文件一定不能包含对象定义或者非inline函数定义

SF.2: A .h file must not contain object definitions or non-inline function definitionsSF.2:.h文件一定不能包含对象定义或者非inline函数定义Reason(原因)Including entities subject to the one-definition rule leads to linkage e...

weixin_32043813的博客 263

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

深入理解C++在.h头文件中定义函数导致的multiple definition

问题:某个头文件中声明并定义了一个函数,然后在多个源码文件中调用该函数,编译链接时出现了该函数multiple definition问题,在头文件中添加了 #ifndef 头也不行,经过尝试发现如果将该函数的声明和定义分开到.h和.cpp文件之后问题消失,为什么不能将函数直接定义在.h文件中呢? 针对该问题,抽象出如下几个问题: 1头文件中只可放置函数声明,不可放置函数定义吗? 以下面的程序为例:...

sksukai的博客 1万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

inline 的真面目:从函数内联到 C++17 inline 变量

写法定义位置风险+ 类外类外,必须恰好一个 TU忘了写 →;多个 TU 都写 → 重定义类内,头文件自洽无,推荐结论:现代 C++ 写类静态成员,一律加inline写在类里。这是 Core Guidelines 推荐的头文件友好写法。:涵盖 inline 静态成员的 C++17 新规则。inline从来不是「内联指令」,而是「允许在多个翻译单元重复定义的链接许可(ODR 例外)」;函数到底内不内联,由优化器和-O2说了算,跟这个关键字无关。它真正的现代价值在 C++17 的。

weixin_38244193的博客 334

C++-头文件书写规范(一):只能存在变量、函数的声明, 而不能放定义【例外:①可以写static、const对象的定义;②可以写内联函数(inline)的定义;③可以写类(class)的定义】

通过“定义只能有一次”的规则,我们很容易可以得出,头文件中应该只放变量和函数的声明,而不能放它们的定义。因为一个头文件的内容实际上是会被引入到多个不同的.cpp文件中的,并且它们都会被编译。放声明当然没事,如果放了定义,那么也就相当于在多个文件中出现了对于一个符号(变量或函数)的定 义,纵然这些定义都是相同的,但对于编译器来说,这样做不合法。它们本身并不参与编译,但实际上,它们的内容却在多个.cpp文件中得到了编译。所以,应该记住的一点就是,.h头文件中,只能存在变量或者函数的声明, 而不要放定义。

u013250861的博客 1709

C++中inline函数的定义为什么要放在头文件中?头文件中“只定义一份”是什么意思?const object 和inline函数是“一次定义规则”

inline   可以放在   .cpp   中,但此时只有本   cpp   文件可以用它         如果要做成公用的,就必须放在   .h   中,如果不想放在   .h   中,就必须每个   cpp   文件拷贝一份。         其实,即使放在   .h   中,也是每个   cpp   文件拷贝一份的,只不过是编译器替你完成这种拷贝罢了。         inline   函

rufeng18的专栏 5221

在头文件中用宏定义来避免重复包含,仍然会出现函数重定义的错误

1. 在头文件包含中用了宏定义,还是会出现函数重定义的错误,表现为“error LNK2005: 已经在*.obj中定义“。 主要原因是在头文件中定义了函数。 因为对每个包含这个头文件的cpp文件而言,都要编译生成一个有这个函数实体的obj文件,对于单个文件而言没有重复定义。但对于整个工程而言,在链接的时候会因为有多个函数定义实体,而报错。 2.  为避免重复定义, 结构体的定义和静态数据的

kkForWork的专栏 4440

C++核心准则SF.2:.h文件一定不能包含对象定义或者非inline函数定义

SF.2: A.hfile must not contain object definitions or non-inline function definitions SF.2:.h文件一定不能包含对象定义或者非inline函数定义 Reason(原因) Including entities subject to the one-definition rule leads to linkage errors. 对于包含实物对象违反一次定义规则,会导致链接错误。 Example(示...

面向对象思考 616

c++面试:类定义为什么可以放到头文件中

在C++中,定义和声明是两个不同的概念,它们各自有着明确的用途和含义。理解这两者的区别对于编写正确且高效的C++代码至关重要。声明是指向编译器告知某个变量、函数或类的存在及其类型,但并不分配实际的存储空间。声明的主要目的是让编译器知道如何解析程序中的符号引用。例如:// 声明一个名为a的整型变量,但不分配内存// 声明一个名为add的函数,但不提供实现// 前置声明,仅声明了MyClass的存在声明允许你在代码的一个部分提到某个实体,并在另一个部分提供其实现或定义。

he_wen_jie的博客 1554

C++的内部链接、外部链接及inline函数的探讨

先是几个概念: 编译单元: 首先明确,只有源文件(.cpp/.c)才能被编译器编译。预处理器首先递归包含头文件,形成一个含所有必要信息的单个源文件,此源文件就是一个编译单元。 我可将其理解为被预处理后,包含头文件的.cpp文件。 内部连接: 如果一个编译单元(.cpp)内的名称对编译单元(.cpp)来说是局部的,在链接的时候其他的编译单元无法链接到它且不会与其它编译单元(.cpp)中...

brahmsjiang的专栏 2001

C/C++:头文件与cpp文件的声明/定义

一、头文件 1、 一般来说,头文件仅仅用于声明,相应的定义要放在对应的cpp文件中。  声明的内容一般可以是:1. 类定义体;2.类中的成员方法; 3. 类外的函数; 4. 类外的变量;5. 类型。   一个文件(比如main.cpp)包含(#include)了一个头文件(比如item.h),就相当于声明了Item.h中声明的所有内容。 2、但是const常量,inline函数,static函数...

yongjunhe的专栏 5488

C++中定义自己的头文件

由多个文件组成的程序需要一种方法连接名字的使用和声明,在C++中是通过头文件实现的。头文件一般包括类的定义,extern 变量的声明和函数的声明。使用或定义这些实体的文件要包含适当的头文件。 头文件的正确使用有两个好处:保证所有文件使用给定实体的同一声明;当声明需要修改时,只有头文件需要更新。在定义头文件时要注意头文件中所做的声明在逻辑上应该是适于放在一起的,否则,编译头文件会花费较长时间。

Boiler UP! 8710

【转载】c++普通函数在头文件定义报重复定义的错误。而class定义不会

为什么class C在header中定义了,并且在其他两个cpp中都include了,结果,链接时不会报重复定义的错误?

Antonic_的博客 678
上一篇: member selection 运算符是什么
下一篇: 内联失败函数变成static函数的一些问题
Savitch
博客等级 码龄16年 84粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值