파일 구조

지금까지 우리는 하나의 파일 안에서 모든 코드를 작성했습니다. 하지만 실제 프로그램은 수십, 수백 개의 파일로 이루어져 있습니다. C++에서는 이 파일들을 어떻게 정리할까요?

C++은 다른 언어들과 조금 다릅니다. packagemodule 같은 키워드 대신, **헤더 파일(.h)**과 **소스 파일(.cpp)**을 나누고, #include로 연결하는 방식을 사용합니다.


헤더 파일과 소스 파일

C++에서는 하나의 기능을 만들 때 보통 두 개의 파일을 만듭니다:

  • 헤더 파일 (.h): “이런 기능이 있습니다”라고 선언하는 파일
  • 소스 파일 (.cpp): 그 기능이 실제로 어떻게 작동하는지 적는 파일
// calculator.h (헤더 파일 - 선언)

int add(int a, int b);
int subtract(int a, int b);
// calculator.cpp (소스 파일 - 구현)

#include "calculator.h"

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

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

왜 굳이 두 파일로 나눌까요? 레스토랑에 비유하면, 헤더 파일은 메뉴판(어떤 요리가 있는지)이고, 소스 파일은 조리법(어떻게 만드는지)입니다. 손님(다른 파일)은 메뉴판만 보면 되지, 조리법까지 알 필요는 없습니다.


#include의 의미

우리가 처음부터 써왔던 #include <iostream>의 의미를 이제 정확히 이해할 수 있습니다.

#include <iostream>

이것은 “iostream이라는 헤더 파일을 여기에 포함시켜라”라는 뜻입니다.

#include에는 두 가지 형태가 있습니다:

#include <iostream>      // 표준 라이브러리에서 가져오기
#include "calculator.h"  // 내가 만든 파일에서 가져오기
  • < >: C++이 미리 만들어 놓은 표준 도구함에서 가져옵니다
  • " ": 현재 프로젝트 안에서 가져옵니다

다른 파일의 기능 사용하기

// main.cpp

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

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

#include "calculator.h"를 적으면, calculator.h에 선언된 함수들을 사용할 수 있게 됩니다.


네임스페이스 (namespace)

프로젝트가 커지면, 같은 이름의 함수가 여러 곳에 생길 수 있습니다. 이를 방지하기 위해 C++은 네임스페이스를 사용합니다.

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;
    }
}

사용할 때는:

int result1 = math_utils::add(3, 5);           // 숫자 덧셈
std::string result2 = string_utils::add("Hello", " World"); // 문자열 연결

우리가 매번 써왔던 std::가 바로 이것입니다! std는 C++ 표준 라이브러리의 네임스페이스입니다.

  • std::cout → std 네임스페이스에 있는 cout
  • std::endl → std 네임스페이스에 있는 endl

실제 프로젝트는 이렇게 생겼습니다

my_game/
├── CMakeLists.txt            ← 빌드 설정 파일
├── main.cpp                  ← 프로그램 시작점
├── include/                  ← 헤더 파일 모음
│   ├── character.h
│   ├── weapon.h
│   └── utils.h
└── src/                      ← 소스 파일 모음
    ├── character.cpp
    ├── weapon.cpp
    └── utils.cpp

이렇게 정리하면, “캐릭터 관련 기능이 궁금하면 character.h를 보고, 구현이 궁금하면 character.cpp를 보면 되겠구나!” 하고 바로 찾을 수 있습니다.


C++의 표준 라이브러리

자주 사용되는 표준 헤더 파일들:

헤더설명
<iostream>입출력 (cout, cin)
<string>문자열 처리
<vector>동적 배열
<map>키-값 쌍 자료구조
<algorithm>정렬, 검색 등 알고리즘
<cmath>수학 함수
#include <vector>
#include <algorithm>

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

정리하자면:

  • 헤더 파일 (.h) = 기능을 선언하는 메뉴판
  • 소스 파일 (.cpp) = 기능을 구현하는 조리법
  • #include = 다른 파일의 코드를 가져다 쓰기
  • namespace = 이름 충돌을 방지하는 울타리 (std:: 의 정체!)
  • 표준 라이브러리 = C++이 미리 만들어 놓은 도구 모음

C++의 파일 구조는 처음에는 복잡하게 느껴지지만, 이 원리를 이해하면 대규모 프로그램도 체계적으로 관리할 수 있습니다!