文章目录

  • 1、文件类型
    • 1.1、头文件
    • 1.2、cpp源文件
  • 2、多文件的编译

稍微大一点的项目都不会是单个文件的,多文件的好处实在太多,模块开发、分工协作、代码复用、结构清晰、模块更新…不细扯,直接梳理一下C++源代码的文件类型、多文件编译。

1、文件类型

C++程序一般分三类文件:

  • 头文件( .h )。放置各种声明,用于被cpp文件包含。
  • 模块文件(.cpp)。放置一些函数定义,也称为功能模块。
  • 主程序文件(.cpp)。包含main()的文件,程序入口,调用模块文件实现的方法。

1.1、头文件

头文件的存在是为了联系多个源文件,是源文件之间的接口。C++与C一样,要求先声明后使用,可是编译的时候是单文件编译的。看一个没有头文件的例子。

//main.cpp
void fun();     //必须先声明,不然调用出错
int main(){fun();       // 调用fun
}
//fun.cpp
#include <iostream>
void fun(){std::cout<<"This is fun."<<std::endl;
}

使用命令g++ main.cpp fun.cpp编译两个文件之后是可以正常运行的。这里你需要知道一点C++编译过程原理:C++把每个文件单独编译出来,再通过链接把编译出来的多个文件组成一个可执行程序。编译的时候只检查函数声明,只要该文件能在之前声明过函数就能编译成功。函数定义是在链接阶段检查的,而链接是多文件共同参与的。上例中,main.cpp必须先声明函数fun()才能通过编译, 尽管没有在main.cpp中定义,但在链接的时候发现fun.cpp定义了该函数,程序正确。

但是,每次使用其它文件的函数前都要自己先声明显然很繁琐也容易出错。所以,我们把声明类语句放到一类文件里,称之“头文件”,如果你需要使用到某个函数,就把它所在的头文件包含进来,头文件的内容会在编译前被粘贴到源文件中,这样在编译的时候就能正常通过了。看使用了头文件之后的例子。

//main.cpp
#include "header.h"
int main(){fun();
}//header.h
#ifndef HEADER_H
#define HEADER_H
void fun();
#endif//fun.cpp
#include <iostream>
void fun(){std::cout<<"This is fun."<<std::endl;
}

头文件的内容一般都会使用条件编译预处理语句(如上)包住,防止因为依赖关系多次被包含。

既然知道头文件的作用,那哪些东西应该放在头文件?哪些不能放在头文件?很好理解,如果这部分需要复制给每个相关的cpp,就把它放在头文件,如果被多个cpp复制之后,可能导致它们在链接过程出错,就不要放在头文件。 一 一来看:

  • 函数声明:显然应该放在头文件中,前面很清楚。
  • 类定义、结构定义:用函数定义的逻辑想,似乎不能放在头文件中。但它应该放在头文件。第一,每个cpp文件应该有一个定义,在编译的时候编译器才知道怎么为对象分配空间。其次,类型定义不会在内存上分配空间。
  • 模板函数:编译器必须在编译的时候根据函数模板实例化对应的函数,所以应该放在头文件。
  • 内联函数:编译期间被插到调用位置,所以也要放在头文件。
  • 函数定义不要!C++规定一个程序同签名的函数只能有一个定义。如果你把函数定义放在头文件件,并且同一个程序的多个cpp文件包含了该头文件,这样,在链接的时候会发现多个定义版本,链接报错。
  • 变量定义不要!与上面类似,被多个文件包含的时候会出现多次定义同一个变量,链接错误。但是,static变量和extern变量可以,以及宏定义的常量,因为这些在多个文件出现并不会出错。

1.2、cpp源文件

把头文件的东西抽离出去之后,剩下的就可以放在cpp文件了。在cpp文件上,除了需要include对应的头文件之外,没有什么变化。

尽管都是cpp文件,还是有必要理解成模块文件和主程序文件,二者类似功能的提供者和使用者,在实际中,也常常由不同的人开发。

2、多文件的编译

如果是使用Windows下的集成开发环境的,大可直接Build,一键搞定,但你对这个过程的理解就可能差点。所以我以linux上为例,最简单的多文件编译命令:

g++ main.cpp fun.cpp -o out   #列举所有要编译的文件

也可以单独编译成 .o文件之后再链接:

g++ -c main.cpp -o main.o
g++ -c fun.cpp -o fun.o
g++ main.o fun.o -o out

第二种是不是引起了你的疑惑——这么麻烦?可是,这种方式提供了一个优点——模块编译更新。你只需要编译你修改过的文件,再跟其他的链接,无需再次对整个项目编译。

在实际的项目中,项目文件可不是小数目,无论上面的那种方式,你都需要一一列出文件,不实际。IDE工具自然没有这种烦恼。不过Linux也会使用Makefile进行项目管理,实现自动编译。行了,又多了一样要学。

我终于把C++多文件编程理解透彻了相关推荐

  1. C语言模块化开发,深入多文件编程

    目录 文章目录 目录 多文件编程 项目分割 避免命名冲突 项目生成的过程 预处理 编译 汇编 链接 语言发展的过程 机器语言 汇编语言 C语言 高级语言 编译的本质 目标文件里藏着什么 可执行文件 链 ...

  2. linux文件编程(open、write、read、creat、lseek函数)

    文件编程内容比较多,如文件系统原理及访问机制文件在内核中的管理机制,什么是文件信息节点iNode.文件共享.文件权限.各种用户对其权限等等.以下主要记录如何用代码操作文件,实现文件的创建.打开.编辑等 ...

  3. c语言const常量用法,C++ const常量在多文件编程中的3种用法

    <C++多文件编程是什么>一节提到,多文件编程中代码的划分原则是:将变量.函数或者类的声明部分存放在 .h 文件,对应的实现部分放在 .cpp 文件中.值得一提得是,此规律适用于大部分场景 ...

  4. Visual C# 资源文件编程--创建资源文件

    资源文件顾名思义就是存放资源的文件.资源文件在程序设计中有着自身独特的优势,他独立于源程序,这样资源文件就可以被多个程序使用.同时在程序设计的时候,有时出于安全或者其他方面因素的考虑,把重要东西存放在 ...

  5. 手机c语言多文件编程,C语言多文件编程

    今天,IT培训网小编为大家总结的是C语言,C语言多模块开发(多文件编程). 目前为止,我们编写的大部分C语言程序都只包含一个源文件,没有将代码分散到多个模块中,对于只有几百行的小程序来说这或许可以接受 ...

  6. [Linux系统编程]_文件编程(一)

    嵌入式之路,贵在日常点滴 ---阿杰在线送代码 目录 一.系统调用 1.1 什么是系统调用 1.2 什么是库函数 1.3 将hello写入到文件1.txt流程 1.4 为什么要有缓冲区(补充) 1.5 ...

  7. Linux实验---多文件编程Makefile实验二

    多文件编程Makefile实验指导书 一 实验题目: 二 实验目的 三 实验内容 四 实验步骤 五 实验结果 六.总结 一 实验题目: 多文件编程Makefile 二 实验目的 (1) 熟悉Linux ...

  8. Linux基础之文件编程

    文件编程篇 一:文件的打开及创建 二:文件写入操作 三:文件读取操作和文件光标移动操作 四:文件打开创建的补充 五:文件操作原理概述 六:文件操作小应用之实现cp指令 七:文件编程小应用之修改程序的配 ...

  9. linux应用程序接收文件,Linux应用程序学习之文件编程

    Linux应用程序学习之文件系统调用函数编程 上一篇我们了解了Linux系统下函数库的设计方法,这一章我们就来学习一下linux系统下常用的文件操作函数,在进行系统文件操作函数介绍前,我们首先要明白一 ...

最新文章

  1. python从字符串解析方法名
  2. SAP Spartacus Page Layout学习笔记
  3. 首批国家应用数学中心名单公布,哪些高校获批?
  4. Flutter BottomNavigationBar 三分钟实现一个常用APP首页底部导航菜单栏
  5. .Net页面缓存OutPutCache详解
  6. visual studio 设计器不显示_嫦娥上升器为什么不设计成月球勘测器?
  7. 指针变量的所占字节数大小确定
  8. MySQL的连接字符串 concat、concat_ws、group_concat、repeat()函数用法
  9. Mac更换JDK版本
  10. 谷歌浏览器不能上网的解决办法之一
  11. C++刷题: 逆波兰表达式(力扣150题)
  12. 80004005错误代码_0x80004005,小编教你解决0x80004005错误代码的方法
  13. 爬虫日记(23):用scrapy快速地爬取蜂鸟网图片
  14. 通过网线连接两台主机
  15. PTA实验4-1-3 找出最小值 (20分) 本题要求编写程序,找出给定一系列整数中的最小值。
  16. java idea导入ecli项目
  17. 2.1 SSD算法理论
  18. Git本地版本回退与远端版本回退(回滚)
  19. ruby on rails win下安装
  20. 妥妥解决MySqL中文乱码问题,就这么任性

热门文章

  1. Django models 模型
  2. 大佬终于把鸿蒙OS讲明白了,以后我也可以吹喽!
  3. Error while Launching activity
  4. 关于spyder环境配置
  5. pinpoint监控学习笔记
  6. 关于多线程中的面试题
  7. 自制的MATLAB拼图游戏GUI界面版详解(中篇)
  8. LeetCode 力扣 56. 合并区间
  9. WPF DataGridTable
  10. 高性能计算机系统硬件结构图,硬件资源