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::cout→coutlocated in thestdnamespacestd::endl→endllocated in thestdnamespace
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:
| Header | Description |
|---|---|
<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!