C++ Header Files (.h/.hpp): Declarations, Include Guards, and What Belongs Where
이 글의 핵심
Headers carry declarations (and certain definitions like inline/templates). Learn declaration vs definition, guards, forward declarations, and how to avoid multiple-definition and circular include problems.
Introduction
C++ headers (.h, .hpp) carry declarations that describe APIs; source files provide definitions. Headers are how you modularize code and share types across translation units.
1. Header basics
Declaration vs definition
| Declaration | Definition | |
|---|---|---|
| Role | Introduces a name | Provides the actual implementation |
| Duplication | Allowed | One per program (ODR) for most entities |
| Example | int add(int, int); | int add(int a,int b){ return a+b; } |
ODR: a definition must be unique across the whole program (with specific exceptions).
2. Include guards / #pragma once
Prevent the same header text from being processed twice in one TU—otherwise types and inline functions could be redeclared illegally.
3. Worked examples
The Korean article walks through:
- calculator.h/.cpp: class API in header, methods in
.cpp - Template stack: templates usually need full definitions in headers
- forward declaration:
WindowvsWidgetto avoid include cycles - inline helpers in headers: small,
inlinefunctions
4. What can live in headers
- Forward declarations,
enum class, type aliases - Class declarations and inline member definitions (carefully)
inline/constexprfunctions andinlinevariables (C++17+)- Templates (full definition typically visible)
externobject declarations
Generally not: non-inline free function bodies, non-inline global variable definitions (use extern in header + one definition in a .cpp, or inline globals in C++17).
5. Common problems
Multiple definition (ODR)
Do not define non-inline globals in headers included by many .cpp files.
Circular includes
Break cycles with forward declarations and include only where full types are needed.
Include bloat
Include what you use; forward declare heavy dependencies in headers.
Include order in .cpp
Put your matching header first to prove it is self-contained, then system headers, then other project headers.
6. Best practices
Minimal dependencies, include guards/#pragma once, forward declarations, inline for tiny header-only helpers, templates fully in headers.
7. Logger sketch
A small Logger singleton-style API demonstrates header/.cpp split and macro convenience wrappers—see original for full code.
Summary
- Headers: declarations (+ allowed definitions)
- Guards: prevent duplicate inclusion
- Forward declarations: faster builds, fewer cycles
- Templates: definitions in headers
inlinefunctions: can live in headers
Next: Include path, Header guards, Preprocessor.
Related posts
- include errors
- Header guards
- Include path
- Forward declaration
- C++20 modules