분할 구조 (Header / Source File)
하나의 코드를 .h 파일과 .cpp 파일로 나누어 관리하는 방식
일반적으로
.h: 선언(Declaration).cpp: 구현(Definition)
을 담당한다.
장점
코드 관리가 편해짐
기능별로 파일을 분리할 수 있다.
예)
Player.h
Player.cpp
Monster.h
Monster.cpp
Inventory.h
Inventory.cpp
파일 역할이 명확해져 유지보수가 쉬워진다.
협업 시 충돌 감소
여러 사람이 동시에 작업할 때
각자 다른 파일을 수정할 수 있다.
예)
- A : Player.cpp 수정
- B : Inventory.cpp 수정
Git 충돌이 줄어든다.
재사용 가능
헤더만 include 하면
다른 코드에서도 쉽게 사용할 수 있다.
예)
#include "Player.h"
컴파일 속도 개선 가능
변경된 cpp 파일만 다시 컴파일하면 된다.
예)
Player.cpp 수정
↓
Player.cpp만 재컴파일
큰 프로젝트일수록 효과가 커진다.
단점
파일 수 증가
기능 하나를 만들더라도
Player.h
Player.cpp
처럼 최소 두 개의 파일이 필요하다.
프로젝트 규모가 커질수록 파일 관리가 복잡해질 수 있다.
include 남용 시 컴파일 속도 저하
헤더를 include하면
전처리 단계에서 해당 파일 내용이 복사된다.
예)
#include "A.h"
#include "B.h"
#include "C.h"
↓
컴파일 시
A.h 내용
B.h 내용
C.h 내용
이 전부 복사되어 하나의 파일처럼 처리된다.
따라서 불필요하게 많은 헤더를 include하면
컴파일 속도가 느려질 수 있다.
순환 참조(Circular Dependency) 문제
예)
Player.h
#include "Monster.h"
Monster.h
#include "Player.h"
서로를 include하게 되면
컴파일러가 타입을 완성할 수 없어 오류가 발생한다.
해결 방법
전방 선언(Forward Declaration)을 사용한다.
class Monster;
class Player
{
private:
Monster* Target;
};
필요한 경우에만 cpp에서 include한다.
중복 정의 문제
헤더에서 함수를 구현하면
// MyClass.h
void Func()
{
}
해당 헤더를 여러 cpp가 include했을 때
A.cpp
#include "MyClass.h"
B.cpp
#include "MyClass.h"
함수가 여러 번 정의되어
Multiple Definition
오류가 발생할 수 있다.
해결 방법
헤더에는 선언만 작성한다.
// MyClass.h
void Func();
// MyClass.cpp
void Func()
{
}
디버깅이 불편할 수 있음
선언과 구현이 분리되어 있기 때문에
Player.h
↓
Player.cpp
를 계속 오가며 확인해야 한다.
작은 프로젝트에서는 오히려 불편할 수 있다.
캡슐화가 깨질 위험
헤더에 너무 많은 내용을 공개하면
외부 코드가 내부 구현에 의존하게 될 수 있다.
예)
class Player
{
public:
int HP;
int MP;
int Level;
};
외부에서 직접 접근 가능
player.HP = -9999;
해결 방법
필요한 정보만 공개한다.
class Player
{
private:
int HP;
public:
int GetHP() const;
};
정리
분할 구조는
- 코드 관리
- 협업
- 재사용성
측면에서 매우 큰 장점이 있다.
하지만
- include 남용
- 순환 참조
- 중복 정의
문제를 유발할 수 있으므로
- 전방 선언 사용
- 필요한 헤더만 include
- 선언과 구현 분리
를 지켜서 사용하는 것이 중요하다.
'c++ > 기초' 카테고리의 다른 글
| 값 타입과 참조타입 (0) | 2026.06.08 |
|---|---|
| extern (외부 변수) (0) | 2026.06.05 |
| nullptr (0) | 2026.06.05 |
| #define 0 NULL (0) | 2026.06.02 |
| 참조자(Reference) (0) | 2026.05.31 |