浅谈头文件(.h)和源文件(.cpp)的区别

本人原来在大一写C的时候,都是所有代码写在一个文件里一锅乱煮。经过自己开始写程序之后,发现一个工程只有一定是由多个不同功能、分门别类展开的文件构成的。一锅乱煮只会导致代码可读性差、维护性差。但是本人在学习C++的时候,被这章节弄混了。 Source & Header, Separate Files from Classes,里面介绍了一个对于Python写手来说很新的概念。就是头文件和源文件的区别,下面谈谈我自己学习后的理解。

头文件(.h)

头文件用来写 类的声明 (包括类的成员的声明和方法声明)、函数原型#define 常数等,但是很少会写出具体的实现和细节。就好比抽象类一样。

头文件很有意思的是,开头和结尾必须按照以下格式:

#ifndef MYCLASS_H
#define MYCLASS_H // code here #endif

当时我看到这个是极其的不理解和迷茫的,后来阅读了别人的博文才略懂。

首先解释他是干嘛使的,这是防止头文件被重复引用。什么叫被重复引用?就是同一个头文件(.h)在同一个源文件(.cpp)中被include了多次。这种错误常常是因为include嵌套。举个最简单的例子,存在cellphone.h这个头文件引用了#include "huawei.h",之后又有china.cpp这个源文件同时导入了#include "cellphone.h" 和 #include "huawei.h"。此时huawei.h就在一个源文件里引用了两次。

那么,某些时候,只是因为include了两遍,增大了编译器的工作量。如果是小型程序的话还好说,但是大型工程甚至会增长几个小时的编译时间。但是另一些情况,会引起很严重的错误。比如在头文件中定义了全局变量会引起重复定义。

所以就有了我们上面那些看起来乱七八糟的代码,下面开始解释。

#ifndef MYCLASS_H 的意思是 if not define myclass.h,这样看就很好理解了,如果引用这个头文件的源文件不存在myclass.h这个头文件,那么接下行 #define MYCALSS_H, 引入myclass.h。然后就是我们头文件的代码。如果已经有了,直接跳到 #endif。

理论上来说,上面这个片段的MYCLASS_H是可以任意命名的,但是约定俗成的,为了可读性的,我们都把它命名为这个头文件的大写和下划线的形式。如下面这一段代码:

#ifndef HUAWEI_H       // 防止huawei.h被重复引用
#define HUAWEI_H #include <cmath> // 引用标准库
#include "honor.h" // 引用非标准库头文件
...
void Function(); // 全局函数声明
class Mate20{ // 类声明
public: Mate20(); // 构造函数声明
~Mate20(); // 析构函数声明
private:
protected:
}; #endif

上面的代码其实已经很好的解释了头文件的作用——声明。可以看见内部的函数和方法仅仅是声明,而都没有写入具体细节。

源文件(.cpp)

源文件主要写实现头文件中已经声明的那些函数的具体代码。需要注意的是,开头必须#include一下实现的头文件,以及要用到的头文件。那么当你需要用到自己写的头文件中的类时,只需要#include进来就行了。

下面举个例子

我首先写一个头文件Pen.h,里面定义了一个Pen类:

#ifndef PEN_H
#define PEN_H
#include <string>
class Pen
{
public:
Pen(std::string brand); }; #endif

然后我在我的主文件test.cpp中引入了这个头文件:

#include <iostream>
#include "Pen.h"
using namespace std; Pen::Pen(string brand) {
cout << "What brand are you looking for?" << endl;
cout << brand;
} int main() {
Pen pilot("pilot"); } // 输出结果为
/* What brand are you looking for?
pilot */

结果表明,这样引入是正确的。

浅谈头文件(.h)和源文件(.cpp)的区别的更多相关文章

  1. C++中的头文件(.h)和源文件(.cpp)都应该写什么?

    头文件(.h):写定义和声明写类的声明(包括类里面的成员和方法的声明).函数原型.#define常数等,但是一般来说不写具体的实现.注意: 1.在写头文件的时候需要注意,在开头和结尾处必须按照如下样式 ...

  2. 浅谈Linux下/etc/passwd文件

    浅谈Linux 下/etc/passwd文件 看过了很多渗透测试的文章,发现在很多文章中都会有/etc/passwd这个文件,那么,这个文件中到底有些什么内容呢?下面我们来详细的介绍一下. 在Linu ...

  3. 视频基础知识:浅谈视频会议中H.264编码标准的技术发展

    浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...

  4. 浅谈JAVA GUI中,AWT与Swing的区别、联系及优缺点

    浅谈JAVA GUI中,AWT与Swing的区别.联系及优缺点 A.区别 1.发布的时间 AWT是在JDK 1.0版本时提出的 Swing是在AWT之后提出的(JAVA 2) 2. ”重量” AWT是 ...

  5. 浅谈Oracle中物理结构(数据文件等。。。)与逻辑结构(表空间等。。。。。)

    初始Oracle时很难理解其中的物理结构和逻辑结构,不明白内存中和硬盘中文件的区别和联系,我也是初学Oracle,这里就简单的谈谈我我看法. 首先,你需要明白的一点是:数据库的物理结构是由数据库的操作 ...

  6. 浅谈hadoop中mapreduce的文件分发

    近期在做数据分析的时候.须要在mapreduce中调用c语言写的接口.此时就须要把动态链接库so文件分发到hadoop的各个节点上,原来想自己来做这个分发,大概过程就是把so文件放在hdfs上面,然后 ...

  7. 头文件 .h 与源文件 .ccp 的区别

    .h 文件一般是用来定义的,比如定义函数.类.结构体等: .cpp 文件则是对头文件的定义进行实现. include .h文件,可以调用你声明的函数.类等.当然,比较简单的类.函数,你也可以直接在头文 ...

  8. 浅谈2D游戏设计模式2- WZ文件详解(UI.WZ)之MapLogin.img(1)

    玩过冒险岛的人都知道有一个WZ文件,那么这个WZ文件的内部是怎么样的呢,今天我就带大家一探究竟. 说实在的,我这是第一次接触WZ文件,但是却让我很震撼,为什么很震撼,因为这个居然是用VS2010写的! ...

  9. 浅谈odoo 后台与前端文件(附件)的存储与下载

    odoo 后台与前端文件(附件)存储与下载实现 笔记太多了很乱,想想还是写博客的好,慢慢更 当然了,前提是你已经配好了odoo开发环境 一.odoo后台界面实现附件的上传和下载 1).在应用中搜索下图 ...

随机推荐

  1. C#桌面开发的未来-WebWindow

    WebWindow源码作者博客基于Chromium的Edge体验体验方式一:体验方式二:预期目标:遗留的问题 WebWindow WebWindow是跨平台的库. Web Window的当前实验实现可 ...

  2. PHP的for循环

    For循环执行代码块指定的次数,或者当指定的条件为真时循环执行代码块.for循环用于您预先知道脚本需要运行的次数的情况 for(初始值:条件:增量) { 要执行的代码: } <html> ...

  3. 【Python】2.13学习笔记 数学函数和随机函数

    我死了,今天看课看过头了,忘了发作业,被典明批评 而且化学作业还是瞎搞的,直接就发了 我觉得我已经提前死亡了,现在不死亡,开学也会的 函数 挺容易的,有很多语言之间重合的部分 注意 在使用某些数学函数 ...

  4. CentOS7采用tar.gz包方式安装Mysql5.7

    软件:VMware Linux版本:CentOS 7 一.安装mysql(采用tar.gz包安装Mysql5.7) 1.安装开发工具包 [root@localhost ~]# yum groups m ...

  5. 今天开dev的时候,config update一下别人的,但是忘了自己改过目录了,导致光看ip,想了半天,为什么接口不对

    今天开dev的时候,config update一下别人的,但是忘了自己改过目录了,导致光看ip,想了半天,为什么接口不对 baseUrl: {     //     // dev: 'http://1 ...

  6. JavaScript数组排序(冒泡排序、选择排序、桶排序、快速排序)

    * 以下均是以实现数组的从小到大排序为例 1.冒泡排序 先遍历数组,让相邻的两个元素进行两两比较 .如果要求小到大排:最大的应该在最后面,如果前面的比后面的大,就要换位置: 数组遍历一遍以后,也就是第 ...

  7. Spinner 用法

    </Spinner> <TextView android:layout_width="wrap_content" android:layout_height=&q ...

  8. Mac下 eclipse target runtime com.genuitec.runtime 解决方法

    Mac下 eclipse target runtime com.genuitec.runtime 解决方法 解决步骤如下: 首先是找到工程项目一个名叫.settings的文件夹,里面有个叫 org.e ...

  9. nim博弈 LightOJ - 1253

    主要是写一下nim博弈的理解,这个题有点奇怪,不知道为什么判断奇偶性,如果有大佬知道还请讲解一下. //nim博弈 //a[0]~a[i] 异或结果为k 若k=0 则为平衡态 否则为非平衡态 //平衡 ...

  10. vs编译器中不允许使用scanf()的情况

    问题1描述: vs编译器中,不允许使用scanf()函数. error C4996: 'scanf': This function or variable may be unsafe. Conside ...