.h 헤더파일 내용이 중복되면 컴파일 에러가 발생한다.
이걸 방지하기 위해 사용되는 방법들을 알아보겠다.
먼저, 만보기 프로그램을 만든다고 생각해보자.
만보기에는 두 가지 버튼이 있다. 리셋 버튼과 숫자를 세는 버튼, reset & count 버튼으로 구성됐다고 하자.
이 프로그램을 만들기 위해 만보기의 기본적인 기능을 가지는 클래스인 Counter 클래스를 만들어보자.
● Counter 클래스 명세
만보기를 나타내는 클래스를 선언한다. 만보기 객체는 값을 0으로 지울 수 있고, 값을 1씩 증가시킬 수 있고, 현재 만보기의 값을 알려주는 기능이 있어야 한다.
▷ 행위
메소드 | 비고 |
void reset() | 만보기의 값을 0으로 초기화한다. |
void count() | 만보기의 값을 +1 증가시킨다. |
int getValue() | 만보기의 현재 값을 알려준다. |
▷ 속성
속성 | 비고 |
int value | 만보기의 현재 값을 저장한다. |
▷ Counter 클래스
Counter 클래스 |
-value:int |
+reset() : void +count() : void +getValue() : int |
● 소스 파일의 구성
● 헤더파일 내용의 중복 경우
▷ Case 1
/* Counter.h */
class Counter {
//클래스 멤버 선언
....
};
+
/* MainRtn.cpp */
#include "Counter.h"
int main()
{
....
}
선행처리 후 파일이 아래와 같이 해석된다.
▼
/* 선행처리 결과 */
class Counter {
//클래스 멤버 선언
....
};
int main()
{
....
}
이렇게 되면 정상인데 아래와 같은 상황이 발생할 수도 있다.
▷ Case 2
/* Counter.h */
class Counter {
//클래스 멤버 선언
....
};
+
/* ClassA.h */
#include "Counter.h"
class ClassA {
....
};
+
/* MainRtn.cpp */
#include "Counter.h"
#inculde "ClassA.h"
int main()
{
....
}
선행처리 후 파일이 아래와 같이 해석된다.
▼
/* 선행처리 결과 */
class Counter {
//클래스 멤버 선언
....
};
#include "ClassA.h"
int main()
{
....
}
▼
/* 선행처리 결과 */
class Counter {
//클래스 멤버 선언
....
};
#include "Counter.h"
class ClassA{
....
};
int main()
{
....
}
▼
/* 선행처리 결과 */
class Counter {
//클래스 멤버 선언
....
};
class Counter {
//클래스 멤버 선언
....
};
class ClassA{
....
};
int main()
{
....
}
위와 같이 클래스 멤버를 중복해서 선언하게 된다. --> 에러!!!
이런 상황을 방지하기 위한 방법을 알아보자.
● 헤더파일 내용의 중복 include 방지 방법 1
#ifndef SOMETHING 은 if not defined SOMETHING,
즉, SOMETHING이 정의되어 있지 않다면! 이란 뜻이다.
정의되어 있지 않으면 참이므로 다음 문장인
#define SOMETHING으로 가서 정의를 하고 클래스 선언문을 선언한다.
정의되어 있다면 거짓이 되므로 #endif로 가서 SOMETHING을 정의하지 않는다.
자세히 아래 예를 통해 알아보자.
/* Counter.h */
#ifndef COUNTER_H_INCLUDED
#define COUNTER_H_INCLUDED
class Counter {
//클래스 멤버 선언
....
};
#endif
+
/* ClassA.h */
#ifndef CLASSA_H_INCLUDED
#define CLASSA_H_INCLUDED
#include "Counter.h"
class ClassA {
....
};
#endif
+
/* MainRtn.cpp */
#include "Counter.h"
#include "ClassA.h"
int main()
{
....
}
선행처리 결과
▼
class Counter {
//클래스 멤버 선언
....
};
//COUNTER_H_INCLUDED 정의
// #include "Counter.h" --> #ifndef 에서 바로 #endif로 가서 중복선언되지 않는다.
class ClassA {
....
};
//CLASSA_H_INCLUDED 정의
int main()
{
....
}
처음 Counter.h로 Counter 클래스를 정의했고, 그 다음으로 ClassA.h를 통해 ClassA 클래스를 정의한다.
ClassA.h에 #include "Counter.h"가 있지만 이미 위에서 COUNTER_H_INCLUDED 됐기 때문에, Counter.h가 정의됐기 때문에 정의하지 않고 건너 뛰어서 #endif로 간다. 중복 선언을 막을 수 있다. 가장 보편적으로 사용하는 방법이다!
● 헤더파일 내용의 중복 include 방지 방법 2
#pragma once를 적용하면 헤더파일이 한 번만 적용된다. (비교적 최근 컴파일러에서만 사용 가능하니 적용가능한지 확인하고 사용해야 한다.)
/* Counter.h */
#pragma once
class Counter {
//클래스 멤버 선언
....
};
#endif
+
/* ClassA.h */
#pragma once
#include "Counter.h"
class ClassA {
....
};
#endif
+
/* MainRtn.cpp */
#include "Counter.h"
#include "ClassA.h"
int main()
{
....
}
선행처리 결과
▼
class Counter {
//클래스 멤버 선언
....
};
class ClassA {
....
};
int main()
{
....
}
이런 간단한 선행처리기(#include, #ifndef 등)를 알고 있으면 디버깅 시간을 줄일 수 있다~!
'Programming > C++' 카테고리의 다른 글
C++ 언어 기초 (7) - 디폴트/복사/이동 생성자 (0) | 2020.08.28 |
---|---|
[C++] const 사용 시 주의점 (0) | 2020.08.27 |
C++ 언어 기초 (6) - 클래스와 객체 (0) | 2020.08.27 |
C++ 언어 기초 (5) - 함수 (0) | 2020.08.26 |
C++ 언어 기초 (4) - 포인터, 동적 메모리 할당, 참조 (0) | 2020.08.26 |