File Structure

Until now, we have written all our code in a single file. However, real-world programs consist of dozens or hundreds of files. How do we organize these files in C++?

C++ is a bit different from other languages. Instead of keywords like package or module, it uses Header files (.h) and Source files (.cpp) and connects them using #include.


Header Files and Source Files

In C++, you usually create two files for a single feature:

  • Header File (.h): A file that declares, “These features exist.”
  • Source File (.cpp): A file that describes how those features actually work.
// calculator.h (Header file - Declaration)

int add(int a, int b);
int subtract(int a, int b);
// calculator.cpp (Source file - Implementation)

#include "calculator.h"

int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

Why split them into two files? Think of a restaurant: the header file is the menu (what dishes are available), and the source file is the recipe (how to make them). A customer (another file) only needs to see the menu; they don’t need to know the recipe.


The Meaning of #include

Now we can accurately understand the meaning of #include <iostream>, which we’ve been using from the start.

#include <iostream>

This means “Include the contents of the iostream header file here.”

There are two forms of #include:

#include <iostream>      // Import from standard library
#include "calculator.h"  // Import from files I created
  • < >: Brings tools from C++‘s pre-made standard toolbox.
  • " ": Brings files from within the current project.

Using Features from Other Files

// main.cpp

#include <iostream>
#include "calculator.h"

int main() {
    int result = add(3, 5);
    std::cout << result << std::endl; // 8
    return 0;
}

By adding #include "calculator.h", you can use the functions declared in calculator.h.


Namespace

As a project grows, functions with the same name might appear in multiple places. To prevent this, C++ uses Namespaces.

namespace math_utils {
    int add(int a, int b) {
        return a + b;
    }
}

namespace string_utils {
    std::string add(std::string a, std::string b) {
        return a + b;
    }
}

To use them:

int result1 = math_utils::add(3, 5);           // Numeric addition
std::string result2 = string_utils::add("Hello", " World"); // String concatenation

The std:: we have been using is exactly this! std is the namespace of the C++ Standard Library.

  • std::coutcout located in the std namespace
  • std::endlendl located in the std namespace

What a Real Project Looks Like

my_game/
├── CMakeLists.txt            ← Build configuration file
├── main.cpp                  ← Program entry point
├── include/                  ← Collection of header files
│   ├── character.h
│   ├── weapon.h
│   └── utils.h
└── src/                      ← Collection of source files
    ├── character.cpp
    ├── weapon.cpp
    └── utils.cpp

Organizing this way makes it easy to find what you need: “If I’m curious about character features, I’ll look at character.h; if I’m curious about the implementation, I’ll look at character.cpp!”


C++ Standard Library

Commonly used standard header files:

HeaderDescription
<iostream>Input and output (cout, cin)
<string>String manipulation
<vector>Dynamic arrays
<map>Key-value pair data structures
<algorithm>Algorithms like sorting and searching
<cmath>Mathematical functions
#include <vector>
#include <algorithm>

std::vector<int> numbers = {3, 1, 4, 1, 5};
std::sort(numbers.begin(), numbers.end());

To summarize:

  • Header File (.h) = A menu declaring features
  • Source File (.cpp) = A recipe implementing features
  • #include = Using code from other files
  • namespace = A boundary to prevent name conflicts (The truth behind std::!)
  • Standard Library = A collection of tools pre-made by C++

C++ file structure might feel complex at first, but once you understand these principles, you can manage even massive programs systematically!