.h和.cpp文件的区别

本文详细解释了C++编程中头文件(.h)与源文件(.cpp)的区别和作用。阐述了如何通过头文件实现代码复用,以及extern和static关键字如何帮助管理函数与变量的链接属性。
部署运行你感兴趣的模型镜像

 

关于头文件和源文件的分别

首先,我们可以将所有东西都放在一个.cpp文件内.

然后编译器就将这个.cpp编译成.obj,obj是什么东西?

就是编译单元了.一个程序,可以由一个编译单元组成,

也可以有多个编译单元组成. 如果你不想让你的源代码变得很难阅读的话,

就请使用多个编译单元吧.(一个函数不能放到两个编译单元里面,但两个以上

就可以分别放在一个单元,也就是cpp里面)

    那么就是一个.cpp对应一个.obj,然后将所有的obj链接起来(通过一个叫链接器的程序),

组成一个.exe,也就是程序了.

    如果一个.cpp要用到另一个.cpp定义的函数怎么办? 只需在这个.cpp种写上他的函数声明

就可以了.其余工作由链接器帮你完成,你可以随便调用该函数.

    链接器将所有的obj连接起来,但是如果碰巧有相同的函数或外部变量怎么办?他如何识别?

一般来说是不能允许在同一个程序中,出现两个一样的函数名或外部变量名.

    但是只得庆幸的是,c++可以通过一种叫做链接属性的关键字来限定,你这个函数是属于整个程序

公用的,还是只是在一个编译单元obj里面使用的.

    这些关键字就是extern 和 static; extern是外部链接的意思,也就是除了这个单元,外部的单元

也是能够访问这个函数的.static 是内部链接,自属于自己单元.

说了这么久,还没有说.h的作用呢?

    其实没有.h也能很好的工作,但是当你发现一个外部链接的函数或外部变量,需要许多份

声明,因为c++这种语言,在使用函数和变量的时候,必须将他声明,为何要声明?声明之后才

知道他的规格,才能更好的发现不和规格的部分.你别妄想一个编译单元,会自动从另一个

编译单元那里得到什么信息,知道你是如何定义这个函数的.

    所以说,只要使用到该函数的单元,就必须写一份声明在那个.cpp里面,这样是不是很麻烦,

而且,如果要修改,就必须一个一个修改.这真让人受不了.


.h就是为了解决这个问题而诞生,他包含了这些公共的东西.然后所有需要使用该函数的.cpp,只需要

用#include包含进去便可.以后需要修改,也只是修改一份内容.


请注意不要滥用.h,.h里面不要写代码,.h不是.cpp的仓库,什么都塞到里面.

如果在里面写代码,当其他.cpp包含他的时候,就会出现重复定义的情况,

比如将函数func(){printf};放到头文件a.h,里面还有一些a.cpp需要的声明等;

然后你发现b.cpp需要用到a.cpp里面的一个函数,就很高兴的将a.h包含进来.

注意,#include并不是什么申请指令,他就是将指定的文件的内容,原封不动的拷贝

进来.


这时候实际上a.cpp和b.cpp都有一个func()函数的定义.

如果这个函数是内部链接static的话,还好,浪费了一倍空间;

如果是extern,外部链接(这个是默认情况),那么根据在同一个程序内不可出现

同名函数的要求,连接器会毫不留情给你一个连接错误!

 

 

 

您可能感兴趣的与本文相关的镜像

Qwen3-8B

Qwen3-8B

文本生成
Qwen3

Qwen3 是 Qwen 系列中的最新一代大型语言模型,提供了一整套密集型和专家混合(MoE)模型。基于广泛的训练,Qwen3 在推理、指令执行、代理能力和多语言支持方面取得了突破性进展

### `.h` 头文件 `.cpp` 源文件的作用及区别 C++ 中 `.h` 文件 `.cpp` 文件在项目结构中具有明确的分工,分别承担不同的职责。这种分离有助于代码的模块化管理、提高可读性,并支持多文件协作开发。 #### `.h` 头文件的作用 `.h` 文件通常用于声明函数、类、结构体、全局变量、常量以及模板定义等。头文件的主要作用是提供接口定义,使得多个源文件可以共享这些声明[^2]。例如: ```cpp // Example.h #ifndef EXAMPLE_H #define EXAMPLE_H class Example { public: void greet(); // 声明 }; #endif // EXAMPLE_H ``` 头文件的内容会被预处理器通过 `#include` 指令复制到源文件中,从而使得源文件能够识别这些声明。在多语言混合项目中,`.h` 文件通常用于 C 语言接口,而 `.hpp` 文件则用于 C++ 接口,以避免因语言差异引发的编译错误[^1]。 #### `.cpp` 源文件的作用 `.cpp` 文件是程序的实现单元,用于编写函数、类成员方法等具体逻辑代码。它是编译器实际编译的对象,负责将声明转化为可执行代码。例如: ```cpp // Example.cpp #include "Example.h" #include <iostream> void Example::greet() { std::cout << "Hello from Example!" << std::endl; } ``` 源文件中通常包含相应的头文件以获取接口定义,并通过实现这些接口来完成程序功能。 #### `.h` `.cpp` 的区别 - **内容结构**:`.h` 文件仅包含声明,而 `.cpp` 文件包含实现。 - **编译方式**:`.cpp` 文件是独立的编译单元,每个 `.cpp` 文件会被单独编译成目标文件(如 `.o` 或 `.obj`),而 `.h` 文件不会被直接编译。 - **命名约定**:虽然编译器并不强制要求 `.h` `.cpp` 文件具有相同的主文件名,但为了便于识别维护,通常会采用相同的主文件名,例如 `Example.h` `Example.cpp`[^3]。 - **重用性**:头文件支持多个源文件的重复引用,而源文件通常只在一个编译单元中使用。 #### 项目中的使用建议 - **头文件**应使用 `#ifndef` 或 `#pragma once` 来防止重复包含,避免编译错误。 - **源文件**应仅实现头文件中声明的内容,避免定义未声明的函数或变量。 - **命名一致性**有助于提升代码可读性维护性,推荐采用类名或功能模块名作为主文件名。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值