헤더파일 분할 작성
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 가 포함되었기 때문에 중복 선언되었다는 오류가 뜬 것이다.
헤더파일 중복 선언 방지
헤더파일의 중복 선언을 방지하기 위해서 전처리기 ifdef 와 ifndef 를 사용할 수 있다.
- 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
헤더파일은 어떤 상황에서 어떻게 사용될지 모르기 때문에 가능하면 중복 선언을 방지해놓는 것이 안정적이다.
'Language > C & C++' 카테고리의 다른 글
[C++] 연산자 오버로딩(operator overloading) (0) | 2024.10.27 |
---|---|
[C++] 프렌드(friend)를 통한 클래스 멤버 접근 (0) | 2024.10.27 |
[C++] 얕은 복사(shallow copy)와 깊은 복사(deep copy) 그리고 복사 생성자 (0) | 2024.10.13 |
[C++] 값에 의한 호출(call by value)과 주소에 의한 호출(call by address) 그리고 참조에 의한 호출(call by reference) (0) | 2024.10.13 |
[C++] 동적 메모리 할당 및 반환 (0) | 2024.10.13 |