C++ 프로젝트에서 윈도우 크기나 게임 설정값을 여러 클래스에서 공유해야 할 때, 가장 효율적인 방법은 namespace와 const를 조합하여 헤더 파일에 선언하는 것입니다.
1. 기본 구조 (Config.h)
namespace를 사용해 이름 충돌을 방지하고, const를 붙여 상수로 선언합니다.
#ifndef CONFIG_H
#define CONFIG_H
namespace WindowConfig {
const int Width = 1280;
const int Height = 720;
}
#endif
2. 왜 반드시 const를 붙여야 하는가?
헤더 파일에 int Width = 1280;과 같이 일반 변수를 선언하고 여러 .cpp 파일에서 #include하면 중복 정의(Multiple Definition) 에러가 발생합니다.
원인
#include는 해당 파일의 내용을 그대로 복사 붙여넣기 합니다. 따라서 여러 소스 파일이 동일한 헤더를 포함하면, 링크(Link) 단계에서 이름이 같은 전역 변수가 여러 개 존재하는 것으로 간주되어 충돌이 일어납니다.
해결
const 키워드를 붙이면 해당 변수는 기본적으로 내부 연결(Internal Linkage) 속성을 갖게 됩니다. 즉, 각 소스 파일마다 독립적인 상수가 생성된 것으로 취급되어 이름이 겹쳐도 충돌 에러가 발생하지 않습니다.
3. 메모리 중복 문제와 최적화
const를 사용해 파일마다 상수가 중복 생성되면 메모리 낭비가 발생할 것 같지만, 실제로는 그렇지 않습니다.
상수 전개
컴파일러는 const 상수를 발견하면 실행 시점에 메모리 주소를 참조하는 대신, 컴파일 단계에서 해당 변수명을 실제 숫자(예: 1280)로 직접 치환합니다.
최적화
결과적으로 최종 실행 파일에는 변수를 위한 별도의 메모리 공간이 할당되지 않거나, 최적화 과정을 통해 중복이 제거됩니다.
4. 실제 사용 예시
다른 클래스나 메인 함수에서는 해당 헤더만 포함하여 Scope Resolution Operator(::)를 통해 접근합니다.
#include <iostream>
#include "Config.h"
int main() {
// WindowConfig 이름공간의 상수에 접근
int w = WindowConfig::Width;
int h = WindowConfig::Height;
std::cout << "Window Size: " << w << "x" << h << std::endl;
return 0;
}
5. 요약
여러 파일에서 공유할 설정값은 Header 파일에 작성합니다.
이름 충돌 방지를 위해 "namespace" 로 감쌉니다.
빌드 에러를 막기 위해 반드시 "const" 를 붙입니다.
이 방식은 별도의 복잡한 키워드(constexpr, inline 등) 없이도 안전하게 상수를 관리할 수 있는 표준적인 방법입니다.
6. 추가
여기서 한가지 오해를 풀자면, namespace 를 쓴다고 해서 중복 문제가 사라지는 것은 아닙니다.
컴파일러가 에러를 내는 과정
만약 Config.h에 const 없이 int Width = 1280; 만 적고 두 개의 .cpp 파일에서 부르면 다음과 같은 상황이 벌어집니다.
Player.cpp : "우리 집에 WindowConfig::Width라는 애가 살아." (정의 완료)
Enemy.cpp : "우리 집에도 WindowConfig::Width라는 애가 살아." (정의 완료)
링커(Linker) : "잠깐, 너네 둘을 합치려고 보니까 WindowConfig::Width라는 풀네임을 가진 애가 두 명이나 있잖아! 누가 진짜야?"
이름 공간이 Width라는 이름을 WindowConfig::Width로 바꿔주긴 했지만, 그 풀네임 자체가 중복되는 것까지는 막아주지 못하는 것입니다.
const가 마법을 부리는 이유
여기서 const 를 붙이면 규칙이 바뀝니다.
const가 없을 때 : "이 변수는 공공재야. 프로그램 전체에서 단 한 명만 존재해야 해!" (외부 연결)
const가 있을 때 : "이 변수는 이 파일 안에서만 쓰는 개인 소장품이야." (내부 연결)
const를 붙이는 순간, Player.cpp에 있는 WindowConfig::Width와 Enemy.cpp에 있는 WindowConfig::Width는 이름만 같은 별개의 존재가 됩니다. 링커는 "어, 이건 각자 파일 안에서만 쓰는 거구나"라고 판단해서 두 파일을 합칠 때 시비를 걸지 않습니다.
그리고 위에서도 언급했듯이, 각 위치에 값으로 치환되어 중복은 발생하지 않게 됩니다.
'C++' 카테고리의 다른 글
| [C++] 값 복사는 무조건 느리다는 편견과 현대적 기준 (0) | 2026.02.15 |
|---|---|
| 참조 반환(Return by Reference)의 이해와 활용 (0) | 2026.01.27 |
| 베스트 프랙티스(Best Practice) : 전문적인 C++ 코드의 기준 (0) | 2026.01.10 |
| 객체 초기화 방법 (0) | 2026.01.09 |
| new 할당과 초기화 (0) | 2026.01.09 |