C++中的 .h 和 .cpp 区别详解

我们的程序为什么需要头文件 什么是源文件、什么是头文件 我所见到的最好的答案: 通常,在一个 C++ 程序中,只包含两类文件―― .cpp 文件和 .h 文件。其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码;而 .h 文件则被称作 C++ 头文件,里面放的也是 C++ 的源代码。 个人理解: 我们为一个工程或项目所写的所有程序文件都可以被称为源文件。其中源文件包括头文件(C语言的.h文件 \ C+... 阅读详情

在C++编程过程中,随着项目的越来越大,代码也会越来越多,并且难以管理和分析。于是,在C++中就要分出了头(.h)文件和实现(.cpp)文件,并且也有了Package的概念。

对于以C起步,C#作为“母语”的我刚开始跟着导师学习C++对这方面还是感到很模糊。虽然我可以以C的知识面对C++的语法规范,用C#的思想领悟C++中类的使用。但是C#中定义和实现是都在一个文件中(其实都是在类里面),而使用C的时候也只是编程的刚刚起步,所写的程序也只要一个文件就够了。因此对于C++的Package理解以及.h文件和.cpp文件的总是心存纠结。

幸好导师有详细的PPT让我了解,一次对于Package的认识就明白多了。简单讲,一个Package就是由同名的.h和.cpp文件组成。当然可以少其中任意一个文件:只有.h文件的Package可以是接口或模板(template)的定义;只有.cpp文件的Package可以是一个程序的入口。

当然更具体详细的讲解,欢迎下载导师的教学PPT-Package来了解更多。

 

不过我在这里想讲的还是关于.h文件和.cpp文件

知道Package只是相对比较宏观的理解:我们在项目中以Package为编辑对象来扩展和修正我们的程序。编写代码时具体到应该把什么放到.h文件,又该什么放在.cpp文件中,我又迷惑了。

虽然Google给了我很多的链接,但是大部分的解释都太笼统了:申明写在.h文件,定义实现写在.cpp文件。这个解释没有差错,但是真正下手起来,又会发现不知道该把代码往哪里打。

 

于是我又把这个问题抛给了导师,他很耐心地给我详详细细地表述了如何在C++中进行代码分离。很可惜,第一次我听下了,但是没有听太懂,而且本来对C++就了解不深,所以也没有深刻的印象。

经过几个项目的试炼和体验之后,我又拿出这个问题问导师,他又一次耐心地给我讲解了一遍(我发誓他绝对不是忘记了我曾经问过同样的问题),这次我把它记录了下来。

为了不再忘记,我将它们总结在这里。

概览

 非模板类型(none-template)            模板类型(template)            
头文件(.h)            
  • 全局变量申明(带extern限定符)

  • 全局函数的申明

  • 带inline限定符的全局函数的定义

  • 类的定义

  • 类函数成员和数据成员的申明(在类内部)

  • 类定义内的函数定义(相当于inline)

  • 带static const限定符的数据成员在类内部的初始化

  • 带inline限定符的类定义外的函数定义

  • 模板类的定义

  • 模板类成员的申明和定义(定义可以放在类内或者类外,类外不需要写inline)

实现文件(.cpp)
  • 全局变量的定义(及初始化)

  • 全局函数的定义

(无)
  • 类函数成员的定义

  • 类带static限定符的数据成员的初始化

*申明:declaration
   *定义:definition

头文件

头文件的所有内容,都必须包含在

#ifndef  {Filename}              
 #define       {Filename}              
 
 //  {Content of head file}              
 
 #endif        

这样才能保证头文件被多个其他文件引用(include)时,内部的数据不会被多次定义而造成错误

inline限定符

在头文件中,可以对函数用inline限定符来告知编译器,这段函数非常的简单,可以直接嵌入到调用定义之处。

当然inline的函数并不一定会被编译器作为inline来实现,如果函数过于复杂,编译器也会拒绝inline。

因此简单说来,代码最好短到只有3-5行的才作为inline。有循环,分支,递归的函数都不要用做inline。

对于在类定义内定义实现的函数,编译器自动当做有inline请求(也是不一定inline的)。因此在下边,我把带有inline限定符的函数成员和写在类定义体内的函数成员统称为“要inline的函数成员”

非模板类型

全局类型

就像前面笼统的话讲的:申明写在.h文件。

对于函数来讲,没有实现体的函数,就相当于是申明;而对于数据类型(包括基本类型和自定义类型)来说,其申明就需要用extern来修饰。

然后在.cpp文件里定义、实现或初始化这些全局函数和全局变量。

不过导师一直反复强调:不许使用全局函数和全局变量。用了之后造成的后果,目前就是交上去的作业项目会扣分。当然不能用自有不能用的理由以及解决方案,不过不在目前的讨论范围内。

 

自定义类型

对于自定义类型,包括类(class)和结构体(struct),它们的定义都是放在.h文件中。其成员的申明和定义就比较复杂了,不过看上边的表格,还是比较清晰的。

函数成员

函数成员无论是否带有static限定符,其申明都放在.h文件的类定义内部。

对于要inline的函数成员其定义放在.h文件;其他函数的实现都放在.cpp文件中。

数据成员

数据成员的申明与定义都是放在.h文件的类定义内部。对于数据类型,关键问题是其初始化要放在什么地方进行。

对于只含有static限定符的数据成员,它的初始化要放在.cpp文件中。因为它是所有类对象共有的,因此必须对它做合适的初始化。

对于只含有const限定符的数据成员,它的初始化只能在构造函数的初始化列表中完成。因为它是一经初始化就不能重新赋值,因此它也必须进行合适的初始化。

对于既含有static限定符,又含有const限定符的数据成员,它的初始化和定义同时进行。它也是必须进行合适的初始化

对于既没有static限定符,又没有const限定符的数据成员,它的值只针对本对象可以随意修改,因此我们并不在意它的初始化什么时候进行。

 

模板类型

C++中,模板是一把开发利器,它与C#,Java的泛型很相似,却又不尽相同。以前,我一直只觉得像泛型,模板这种东西我可能一辈子也不可能需要使用到。但是在导师的强制逼迫使用下,我才真正体会到模板的强大,也真正知道要如何去使用模板,更进一步是如何去设计模板。不过这不是三言两语可以讲完的,就不多说了。

对于模板,最重要的一点,就是在定义它的时候,编译器并不会对它进行编译,因为它没有一个实体可用。

只有模板被具体化(specialization)之后(用在特定的类型上),编译器才会根据具体的类型对模板进行编译。

所以才定义模板的时候,会发现编译器基本不会报错(我当时还很开心的:我写代码尽然会没有错误,一气呵成),也做不出智能提示。但是当它被具体用在一个类上之后,错误就会大片大片的出现,却往往无法准确定位。

因此设计模板就有设计模板的一套思路和方式,但是这跟本文的主题也有偏。

 

因为模板的这种特殊性,它并没有自己的准确定义,因此我们不能把它放在.cpp文件中,而要把他们全部放在.h文件中进行书写。这也是为了在模板具体化的时候,能够让编译器可以找到模板的所有定义在哪里,以便真正的定义方法。

至于模板类函数成员的定义放在哪里,导师的意见是放在类定义之外,因为这样当你看类的时候,一目了然地知道有那些方法和数据;我在用Visual Studio的时候查看到其标准库的实现,都是放在类内部的。

可能是我习惯了C#的风格,我比较喜欢把它们都写在类内部,也因为在开发过程中,所使用的编辑器都有一个强大的功能:代码折叠。

当然还有其他原因就是写在类外部,对于每一个函数成员的实现都需要把模板类型作为限定符写一遍,把类名限定符也要写一遍。

--------------------- 本文来自 一日看尽长安花 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/TColin/article/details/51593873?utm_source=copy

vs cpp生成h文件_lib 和 dll 的区别、生成以及使用详解 (给CPP开发者加星标,提升C/C++技能)来源:tenoshttps://www.cnblogs.com/TenosDoIt/p/3203137.html【导读】:在日常开发中,我们只需要知道lib是编译时需要的,dll是运行时需要的。如果要完成源代码的编译,有lib就够了。如果要使动态连接的程序运行起来,有dll就够了。本文会带领我们更加清晰的了解二者的区别、生成、使用,一起来看下吧... 阅读详情

相关推荐

h和.cpp文件的区别

当一个.cpp文件需要引用另一个.cpp文件中的类、函数或变量时,可以使用#include指令将.h文件包含进来。这样一来,.h文件中声明的内容就可以在当前.cpp文件中使用,避免了重复编写代码的麻烦。.cpp文件是C++源代码文件的常见扩展名。当我们在.cpp文件中定义了一个函数或实现了一个类时,可以使用#include指令将相关的.h文件包含进来,以便让编译器知道这些函数或类的声明。需要注意的是,头文件通常只包含在.cpp文件中被引用的内容的声明,而不应该包含具体的实现代码,否则可能会导致重定义错误。

CodeNexus的博客 1448

C++ :.cpp【头文件(进行函数、变量、宏、结构体、类声明)】、.cpp【源文件(变量定义、函数实现)】、.hpp(头文件;将.cpp的实现代码混入.h头文件中,定义与实现都包含在同一个文件)

通常,在一个C++程序中,只包含两类文件——.cpp文件和.h文件。其中: .cpp文件被称作C++源文件,里面放的都是C++的源代码; .h文件则被称作C++头文件,里面放的也是C++的源代码。 目前业界的常用格式如下:

u013250861的博客 1万+

C++中文件后缀的区别:cxx、cpp和txx,c、cc和cpp、hpp和h等

文章目录1. cxx、cpp和txx 又开始接触C++了,接触我对代码一开始认识的内容咧,加油 1. cxx、cpp和txx 参考: ITK官方论坛:[Insight-users] Difference between .cxx and .cpp, .txx and .h OSCHINA开源中国:txx cxx cpp 的区别 github的issue:Recognize *.cxx, *.hxx, *.tpp, *txx, *.ipp, and *.ixx files as C++ #539 stack

啷个哩个啷 2万+

.cpp与.h文件的关系详解(预处理、编译、汇编、链接)

C++程序通常分为头文件(.h)和源文件(.cpp):头文件存放函数声明、类定义等接口,源文件存放具体实现。编译过程包括预处理、编译、汇编和链接四个步骤,其中链接器负责将各目标文件中的符号引用与定义进行匹配。关键点在于:1)头文件仅提供声明,源文件提供实现;2)编译器检查语法但不关心实现位置;3)链接阶段通过符号表匹配引用和定义;4)遵循单一定义规则,避免同名冲突。这种分离方式提高了代码的模块化和可维护性,同时通过分步编译提升了效率。

weixin_44115575的博客 1万+

用Matlab搞定Delta并联机器人运动学:从建模到正逆解完整流程(附代码)

本文详细介绍了如何使用Matlab实现Delta并联机器人的运动学分析,包括几何建模、正逆解求解及可视化验证。通过符号计算和数值迭代法,解决非线性方程组问题,并提供完整代码示例,帮助读者快速掌握Delta机器人的运动学计算与应用。

weixin_30955617的博客 170

Cloudflare SaaS 优选IP实战:提升大陆访问速度的配置指南

本文详细介绍了如何通过Cloudflare SaaS优选IP提升中国大陆用户访问速度的配置指南。从基础环境准备到IP筛选方法,再到完整配置流程和效果验证,帮助用户突破免费套餐限制,精准优化网络线路,特别适合跨境电商和面向中国大陆用户的网站优化。

weixin_29231027的博客 662

C++中的 .h 和 .cpp 详解

通俗解释:.h和.cpp差不多就像书和目录的关系吧,目录中对书中的章节和内容进行简单表示,真正的实现是在书里面的。 一般的数据,数据结构,接口,还有类的定义放在.h文件中,可以叫他们头文件,可以#include 到别的文件中。功能实现一般都放在具体的.cpp文件中,这样方便文件管理,节约时间,提高效率。 你完全可以把功能实现一并放在.h文件中,也可以#include一个.cpp文件到另一个源文件中...

a063225的博客 2万+

Lasso的原理及其与其他特征选择方法的比较进行阐述,然后讨论Lasso优点、缺点以及应用场景,最后给出了代码实例

在机器学习领域中,特征选择(feature selection)是指在模型训练前对数据集进行分析,选择其中有助于预测目标变量或影响模型性能的特征,去除不相关或冗余的特征,提升模型的泛化能力。而Lasso回归是一种很流行的用于特征选择的方法之一。Lasso回归(又称LASSO,least absolute shrinkage and selection operator)是一种线性模型中的特征选择方法。

AI天才研究院 3045

【MFC应用创建后核心文件详解】项目名.cpp、项目名.h、项目名Dlg.cpp 和 项目名Dlg.h 的区别与作用

本文介绍了MFC(Microsoft Foundation Classes)编程的入门知识,重点解析了Visual Studio创建MFC项目时自动生成的四个核心文件:MyApp.cpp、MyApp.h、MyAppDlg.cpp和MyAppDlg.h。MyApp文件组负责整个程序的运行管理(应用类),而MyAppDlg文件组则负责主窗口的显示和交互(对话框类)。文章详细说明了每个文件的作用和典型内容,总结了.cpp(实现)和.h(声明)文件的区别,并提供了初学者上手修改代码的实用建议,帮助零基础开发者快速理

深耕CV 1322

Python爬虫实战:医院科室排班智能采集系统 - 从零构建合规且高效的医疗信息爬虫(附CSV导出 + SQLite持久化存储)!

我长期专注 Python 爬虫工程化实战,主理专栏 👉 《Python爬虫实战》:从采集策略到反爬对抗,从数据清洗到分布式调度,持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”,让数据价值真正做到——抓得到、洗得净、用得上。

喵手的博客 1295

[ vulhub漏洞复现篇 ] Drupal XSS漏洞 (CVE-2019-6341)

[ vulhub漏洞复现篇 ] Drupal XSS漏洞 (CVE-2019-6341) Drupal是使用PHP语言编写的开源内容管理框架(CMF),它由内容管理系统(CMS)和PHP开发框架(Framework)共同构成,在GPL2.0及更新协议下发布。Drupal在某些情况下,通过文件模块或者子系统上传恶意文件触发XSS漏洞。

qq_51577576的博客 2201

C++ 中 include 和 include “a.h“ 的区别:头文件搜索路径详解

和搜索路径不同""形式优先在当前源文件目录搜索,然后回退到<>的搜索路径;<>形式直接从编译器的 include 路径开始搜索。这是两者唯一的本质区别。语义约定<>表示“外部依赖”:标准库、系统头文件、第三方库""表示“项目内部”:你自己写的、属于当前项目的头文件这个约定帮助读代码的人快速区分依赖来源实际使用标准库和系统头文件永远用<>第三方库通常用<>(通过-I指定路径)项目内部头文件用""(相对路径)或通过-I<>最重要的是团队统一规范常见误解澄清两种形式都可以找到由-I。

✨ 欢迎来到【Seal ^_^ 的CSDN博客】!✨ 1176

嵌入式面经篇八——进程&线程

记录一些招聘公司在招聘嵌入式软件岗位时的一些问题,此文为第八篇。进程上文:是指进程由用户态切换到内核态时需要保存用户态时CPU寄存器中的值,进程状态以及堆栈上的内容。即保存当前进程的状态,以便再次执行该进程时,能够恢复切换时的状态,继续执行。进程下文:是指切换到内核态后执行的程序,即进程运行在内核空间的部分。中断上文:硬件通过中断触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。

明天你好的博客 1851

【c++】string和string.h和cstring头文件的区别

C/C++中字符串处理的三种方式:1) std::string是C++的字符串类,提供动态内存管理和丰富操作;2) <string.h>是C标准库,提供C风格字符串的操作函数;3) <cstring>是C++对<string.h>的封装。在C++中推荐使用std::string,<cstring>主要用于兼容C代码或性能优化场景。三者的主要区别在于所属语言标准、命名空间和使用方式。

Kevin_Gates的专栏 728

【完整梳理验证】企业微信第三方应用接入全流程java版

由企业内部的开发者自己开发部署,相当于是企业自己的资产,调用接口基本没有任何限制。由SaaS服务商的开发者开发并部署在服务商侧,面向所有企业。需要企业授权使用(先试用后付费),服务商仅可获取企业授权部分的权限,相当于白名单控制。由服务商的开发者开发,但部署在企业内部。一般是线下签约采购方式,因此权限几乎与自建应用无异,企业管理员只需要配置不对服务商开放的敏感权限,相当于黑名单控制。服务商后台地址:企业微信服务商官网企业管理后台地址:企业微信管理后台服务商,可以理解为 SAAS 中的运营端。企业管理端,可以理

Hello, New World! 2742

AI:270-基于ASFF改进YOLOv8检测头的多尺度特征融合方法详解与实战

ASFF是一种基于自适应特征融合的策略,能够动态调整不同尺度特征的融合权重,适应场景中不同大小的目标。传统的YOLOv8检测头使用固定的特征融合策略,而ASFF则通过引入学习参数,使得网络能够根据输入图像的特征自适应地选择不同尺度特征的重要性。这一策略对于检测小目标或尺度变化大的目标具有显著优势。本文提出了一种改进YOLOv8检测头的新方法,通过引入自适应空间特征融合模块(ASFF),有效提升了多尺度目标检测的性能,特别是在小目标检测任务中的表现。

一键难忘的博客 3905

C和C++的区别详解

int<< endl;return0;

m0_74824496的博客 336

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++中.h和.hpp文件的区别

C++中.h和.hpp文件的区别①.h1.1 .h文件是什么1.2为什么要使用.h文件1.3如何使用②.hpp2.1.hpp是什么 ①.h 1.1 .h文件是什么 1.2为什么要使用.h文件   在C++程序中,将所有东西都放在一个.cpp文件内.然后编译器就将这个.cpp编译成.obj( object/objective 编译单元 obj文件解释) 一个程序,可以由一个编译单元组成,也可以有多个编译单元组成. 如果你不想让你的源代码变得很难阅读的话,就请使用多个编译单元吧. 一个函数不能放到两个编译单

weixin_39303983的博客 6441

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

C++ 中到底是应该include .h文件还是应该include .cpp文件

在阅读一个较大的解决方案中,对于其他文件夹下的.h和.cpp文件,有时候#include“XXX.h”文件,有时候是#include“XXX.cpp”文件,而且二者还不能更换。下面就好好分析一下他们二者的区别。 文章目录测试测试:XXX.h和XXX.cpp有没有在解决方案里的差别探究预处理(简单替换)编译和优化(高级语言->汇编语言)生成目标文件(汇编语言->二进制机器语言)链接(汇总成一个目标文件)外部文件夹的h和cpp文件 测试 测试:XXX.h和XXX.cpp有没有在解决方案里的差别   

Be busy living or busy dying 1万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

C++中.cpp和.hpp的区别

c++中 cpp和hpp 首先,我们可以将所有东西都放在一个.cpp文件内,编译器会将这个.cpp编译成.obj,即编译单元。一个程序可以由一个编译单元组成,也可以由多个编译单元组成。一个.cpp对应一个.obj,然后将所有的.obj链接起来(通过一个叫链接器的程序),组成一个.exe,即程序。如果一个.cpp要用到另一个.cpp定义的函数怎么办,只需在这个.cpp中写上它的函数声明。 链接器将所...

Qzx9059的博客 1万+

如何理解C++中的.h文件和.cpp文件

如何理解C++中的.h文件和.cpp文件一、源文件如何根据#include来关联头文件二、头文件如何来关联源文件三、声明与定义的区分:综上所诉   建立一个以类为名字的XX.h文件,声明类,再建立一个相同名字的XX.cpp文件(要#include “XX.h”),实现类中的函数, 在有main 函数的.cpp里声明函数,建一个与函数名一样的.cpp文件,实现该函数;并且要 #include “XX.h” 一、源文件如何根据#include来关联头文件   1.系统自带的头文件用尖括号括起来,这样编译器会在系

weixin_39303983的博客 4026

c++的.h和.cpp文件

.h文件是不对外隐藏的, .cpp文件在编译后对外隐藏---这是最本质的特点和区别 .h和.cpp文件本质上是没有什么区别的,.h文件实现的功能是声明本文件或.cpp文件中需要被别人使用或知道的变量、类型、函数及宏定义等。.h文件就像是一个接口,具体的实现可以在.cpp中也可以在.h中。.cpp中的函数或变量即便是全局的,在没有其他.cpp文件使用的情况下,也可以不写在.h中。 下面参考:h...

小白博客 1万+

h、cpp和hpp头文件之间使用区别

hpp,其实质就是将.cpp的实现代码混入.h头文件当中,定义与实现都包含在同一文件,则该类的调用者只需要include该hpp文件即可,无需再将cpp加入到project中进行编译。而实现代码将直接编译到调用者的obj文件中,不再生成单独的obj,采用hpp将大幅度减少调用 project中的cpp文件数与编译次数,也不用再发布烦人的lib与dll,因此非常适合用来编写公用的开源库。 hpp的优点不少,但是编写中有以下几点要注意: 1、是Header Plus Plus 的简写。 2、与*.h类

Clement 1万+

c++中.h文件和.cpp文件的区别

头文件(.h)主要用于声明函数和类的接口,不包含具体实现代码。源文件(.cpp)主要用于实现头文件中声明的函数和类的具体代码。将声明和实现分开,可以使得代码结构更加清晰,有助于提高代码的可维护性和可读性。同时,头文件的存在使得多个源文件可以共享和重复使用同一组声明,提高了代码的模块化和复用性。

我的博客 6999

C++ 在.h文件中包含头文件和在.cpp文件中包含头文件有什么区别?前置声明

Note:类A在编译的时候不需要拿到类B的定义是因为这里面定义的是指针,而对于指针是不需要定义就可以进行内存布局的,在编译A的类的声明的时候,在进行内存布局的时候是不需要拿到B的定义的。假设有两个类 A 和 B,A 类包含了 B 类的一个指针成员,并且在 A.cpp 文件中使用了 B 类的成员函数。6、如果a.c包含了头文件a.h,a.h包含了头文件b.h,b.c也包含了b.h,那么当b.h发生改变时,a.c和b.c都会重新编译。其中A类有一个成员b是Class B的指针,这个时候可使用类前置声明。

qq_40178082的博客 2535
上一篇: Qt的三大窗口dialog、widget、mainwindow
下一篇: C++ 初始化列表(转载)
Mr.deeplan
博客等级 码龄9年 99粉丝 47原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值