Compiling

  1. class 的 头文件 .h 用于声明Declaration
      • extern variables 跨文件变量声明
      • function prototype 函数原型 {没有body}
      • class declaration > .h 加 pragma once 避免重复定义
  1. class 函数 的 实现文件.cpp 定义与实现Definition
  1. 过程运行文件 main.cpp
  • 每一个.cpp文件都是一个编译单元 compile unit
  • 文件之间的引用是通过包含头文件的方式来实现的
  1. 一个 .cpp 生成一个目标文件 .obj
  1. Linker 会将所有的.obj 文件link成一个.exe 的可执行文件

Makefile utility

  • 自动化程序的编译过程
  • 清晰定义了不同组件之间的结构和依赖关系
将一个project分解成多个目标(.obj)
举个例子:
g++ extern_var.cpp func1.cpp func2.cpp main.cpp -o test 这样的长串有序命令来编译
  • 第一行的main:是定义的一个规则:当前这个组件所依赖的目标文件都有什么;第二行是具体的g++的编译命令语句:如何将这些文件通过g++编译成一个可执行文件
  • makefile的第一行的规则是最终要产出的可执行文件的规则,然后后面的规则按照编译顺序从下到上写的
  • c的含义是只编译生成目标文件,不去做链接
整个makefile就可以理解为一个自动化的编译脚本:包含整个project的文件结构、依赖关系,每个目标文件/可执行文件的编译命令
  • make命令可以运行makefile脚本
最终的结构就可以理解为一个有向无环图
notion image
notion image
notion image
dependency 依赖action 编译命令
tutorial: makefile manual
  • 因为有向无环图的结构存在,当源文件发生更改的时候,就可以自底向上去更新受到影响的编译文件,而不用重新编译整个工程

模板类的实现,不能分开为.h声明和.cpp实现

  • 一般需要放在一个.h文件里面(一般还是将声明和实现都放在.h文件里面会更安全)
原因如下:这是因为模板类的特殊性。模板类的实现必须在编译时可见,这意味着模板类的实现通常需要放在头文件中,而不是单独的源文件中。这样做的原因是模板类的实例化是在编译时进行的,而不是链接时。
当你将模板类的实现放在头文件中时,编译器在编译每个包含该头文件的源文件时都能看到模板的实现,从而能够正确地实例化模板类。
如果你将模板类的实现放在单独的源文件中,编译器在编译包含模板声明的头文件时无法看到模板的实现,从而无法实例化模板类,这就会导致链接时出现未定义引用的错误。
因此,正确的做法是将模板类的实现放在头文件中
Loading...