헤더파일 분할 작성

 

C 나 C++ 에서나 동일하게 작동하나 클래스를 활용하는 C++ 중심으로 설명하겠다.

클래스나 함수 등을 선언부, 구현부로 나누고, 이 파일을 분리해서 작성하면 재사용이 가능하다는 장점이 있다. 선언부는 헤더파일(.h)로 작성하고, 구현부는 cpp 파일로 작성하며, main 함수와 전역 함수, 변수 등은 또 다른 cpp 파일에 작성해 컴파일하면서 병합하는 것이다.

예를 들어 계산기 클래스를 만들고, 이를 실행하는 프로그램을 구현한다면, 다음과 같이 파일을 나누어서 작성할 수 있다.

// Calculator.h

class Calculator{
public:
    int add(int a, int b);
    int sub(int a, int b);
    int mul(int a, int b);
    double div(int a, int b);
};
// Calculator.cpp

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

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

int Calculator::sub(int a, int b) {
    return a - b;
}

int Calculator::mul(int a, int b) {
    return a * b;
}

double Calculator::div(int a, int b) {
    return (double)a / b;
}
// main.cpp

#include <iostream>
#include "Calculator.h"
using namespace std;

int main() {
    Calculator cal;
    int a = 3, b = 1;
    int add = cal.add(a, b), sub = cal.sub(a, b), mul = cal.mul(a, b);
    double div = cal.div(a, b);
    cout << add << ' ' << sub << ' ' << mul << ' ' << div << endl;
    return 0;
}

이때 #include 에서 시스템 헤더파일이나 표준 라이브러리 헤더파일을 사용할 때는 <> 을 사용하지만, 사용자가 만든 헤더파일을 사용할 때는 주로 현재 디렉토리나 지정된 경로에서 찾아야 하기 때문에 "" 을 사용한다.

그런데 중요한 것은 위와같이 코드를 작성한 후 실행하면 헤더파일이 중복 선언되었다는 오류가 뜰 것이다. 다시 코드를 보며 확인해보면 Calculator.cpp 와 main.cpp 에서 모두 Calculator.h 가 포함되었기 때문에 중복 선언되었다는 오류가 뜬 것이다.

 


헤더파일 중복 선언 방지

 

헤더파일의 중복 선언을 방지하기 위해서 전처리기 ifdefifndef 를 사용할 수 있다.

 

  • ifdef

#ifdef MACRO_NAME ~code1~ #else ~code2~ #endif

ifdef 는 if-else 문법와 유사하게 작동한다. MACRO_NAME 이 정의되어 있다면 code1 을 실행하고, 정의되어 있지 않다면 code2 를 실행하며, #endif 로 끝나는 것이다.

예를 들어 위 Calculator.h 를 ifdef 로 수정해보자.

// Calculator.h

#ifdef CALCULATOR_H
#else
#define CALCULATOR_H

class Calculator{
public:
    int add(int a, int b);
    int sub(int a, int b);
    int mul(int a, int b);
    double div(int a, int b);
};

#endif

Calculator 클래스 선언부를 CAUCLUATOR_H 로 정의해주었고, ifdef 를 이용하여 CAUCLUATOR_H 가 정의되어 있다면 아무런 동작도 하지 않고, 정의되어 있지 않다면 CAUCLUATOR_H 를 정의하도록 만들었다. 따라서 헤더파일 중복 선언 오류를 해결할 수 있다.

단 일반적으로 헤더파일 중복 선언을 방지할 때는 ifdef 를 사용하기보다 ifndef 를 사용한다.

 

  • ifndef

#ifndef MACRO_NAME ~code1~ #else ~code2~ #endif

ifdef 와 유사하지만 반대이다. MACRO_NAME 이 정의되어 있지 않다면 code1 을 실행하고, 정의되어 있다면 code2 를 실행하는 것이다.

예를 들어 Cacluator.h 를 수정하면 다음과 같다.

// Calculator.h

#ifndef CALCULATOR_H
#define CALCULATOR_H

class Calculator{
public:
    int add(int a, int b);
    int sub(int a, int b);
    int mul(int a, int b);
    double div(int a, int b);
};

#endif

헤더파일은 어떤 상황에서 어떻게 사용될지 모르기 때문에 가능하면 중복 선언을 방지해놓는 것이 안정적이다.

 

애스터로이드