C++ Header Files (.h/.hpp): Declarations, Include Guards, and What Belongs Where

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

DeclarationDefinition
RoleIntroduces a nameProvides the actual implementation
DuplicationAllowedOne per program (ODR) for most entities
Exampleint 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: Window vs Widget to avoid include cycles
  • inline helpers in headers: small, inline functions

4. What can live in headers

  • Forward declarations, enum class, type aliases
  • Class declarations and inline member definitions (carefully)
  • inline/constexpr functions and inline variables (C++17+)
  • Templates (full definition typically visible)
  • extern object 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

  1. Headers: declarations (+ allowed definitions)
  2. Guards: prevent duplicate inclusion
  3. Forward declarations: faster builds, fewer cycles
  4. Templates: definitions in headers
  5. inline functions: can live in headers

Next: Include path, Header guards, Preprocessor.


  • include errors
  • Header guards
  • Include path
  • Forward declaration
  • C++20 modules