Skip to content

代码结构

头文件和源文件的关系

头文件(.h / .hpp)

头文件主要存放:

  1. 函数声明

    cpp
    int add(int a, int b);  // 只声明,不实现
  2. 类定义 - 类的结构和接口

    cpp
    class Calculator {
    public:
        int add(int a, int b);
        int multiply(int a, int b);
    };
  3. 宏定义、常量定义

    cpp
    #define MAX_SIZE 100
    const double PI = 3.14159;
  4. 模板声明

  5. 内联函数(简单函数直接写在头文件里)

源文件(.cpp)

源文件主要存放:

  1. 函数实现 - 具体怎么做

    cpp
    int add(int a, int b) {
        return a + b;
    }
  2. 类的成员函数实现

    cpp
    int Calculator::add(int a, int b) {
        return a + b;
    }
  3. 全局变量的定义

    cpp
    int globalCounter = 0;  // 这里是定义

代码如何跨文件调用

示例结构:

project/
├── math_utils.h   (头文件 - 菜单)
├── math_utils.cpp (源文件 - 厨房)
└── main.cpp       (主程序 - 顾客)
cpp
#ifndef MATH_UTILS_H  // 防止重复包含
#define MATH_UTILS_H

// 声明函数
int add(int a, int b);
double calculateCircleArea(double radius);

#endif
cpp
#include "math_utils.h"
#include <cmath>

// 实现函数
int add(int a, int b) {
    return a + b;
}

double calculateCircleArea(double radius) {
    return 3.14159 * radius * radius;
}
cpp
#include <iostream>
#include "math_utils.h"  // 包含头文件

int main() {
    int sum = add(5, 3);  // 调用其他文件中的函数
    std::cout << "Sum: " << sum << std::endl;
    
    double area = calculateCircleArea(2.0);
    std::cout << "Area: " << area << std::endl;
    
    return 0;
}

编译和链接的过程:

  1. 编译阶段(每个.cpp独立编译):

    编译器:
    main.cpp + math_utils.h → main.o  (目标文件)
    math_utils.cpp + math_utils.h → math_utils.o
    • 编译器看到 add() 的声明,知道有这个函数
    • 但不知道函数的具体实现在哪里
  2. 链接阶段

    链接器:
    main.o + math_utils.o → 可执行程序
    • 链接器找到 add() 函数的实际位置
    • 把所有目标文件"缝"在一起

重要规则总结:

  1. 头文件只放声明,源文件放实现(内联函数除外)
  2. #include 相当于复制粘贴 - 把头文件内容插入当前位置
  3. 避免循环包含 - 头文件互相包含会导致编译错误
  4. 使用头文件保护 - #ifndef ... #define ... #endif 防止重复定义
  5. 变量声明用 extern
    cpp
    // header.h
    extern int globalVar;  // 声明
    
    // source.cpp  
    int globalVar = 10;    // 定义

为什么这么设计?

  1. 分离接口和实现 - 使用者只看头文件就知道怎么用
  2. 提高编译速度 - 修改一个.cpp文件时,其他文件不需要重新编译
  3. 代码重用 - 多个源文件可以包含同一个头文件
  4. 模块化开发 - 不同的人可以同时开发不同的模块

记住:头文件是"做什么"的说明书,源文件是"怎么做"的具体实现。