profile image

L o a d i n g . . .

article thumbnail image
Published 2020. 5. 26. 22:43
반응형

전방 선언: 선 실행 후 연결

전방 선언은 불필요한 헤더 파일이 복잡하게 포함되는 것을 방지하여, 결과적으로는 컴파일 속도를 향상시킵니다. 객체 수가 많다는 가정하에 빌드 속도 차이가 확연하게 납니다.

 

예제와 함께 알아보기

예를 들어 클래스 A를 지갑, 클래스 B를 통장이라고 했을 때, 클래스 AB는 지갑과 통장에 모두 접근할 수 있는 클래스입니다. 따라서 지갑에 있는 돈을 꺼내어 사용하기도 하고, 통장에 있는 돈을 꺼내서 지갑에 넣기도(또는 그 반대) 하겠죠?

아무런 기능도 하지 않는 클래스들을 만들어, 예시와 함께 보겠습니다.

AB.h

#pragma once
#include "A.h"
#include "B.h"

class AB
{
};

A.h

#pragma once
class A
{
};

B.h

#pragma once
struct tagS
{
	int num;
};

class B
{
};

 

여기서 만약 클래스 A에서 클래스 B 안에 있는 struct을 가져다 써야 하는 경우가 발생한다고 하면 어떻게 코딩하시겠어요? 저는 맨처음에 이렇게 진행했습니다.

A.h

#pragma once
#include "B.h"
class A
{
};

 

A.cpp

#include "A.h"

tagS s;

여기서 주의 깊게 봐야 할 것이 바로 헤더 파일의 #include "B.h"입니다. 만약 B.h에서도 #include "A.h"를 한다면 어떻게 될까요?

앞서 설계한 클래스 관계가 모호해질뿐더러, 헤더 파일에 또다른 헤더 파일이 다시금 걸리면 무한으로 참조하게 될 가능성이 있습니다.

이때, 전방 선언을 이용하면 컴파일 단계에서 헤더 파일("B.h")을 읽지 않기 때문에 해당 위험성을 없앨 수 있습니다. 전방 선언의 사용법은 다음과 같습니다.

 

A.h

#pragma once

struct tagS;	// 1. 전방 선언

class A
{
	//vector<tagS> ...
};

A.cpp

#include "A.h"
#include "B.h"	// 2. cpp 파일에서 include 진행

tagS s;

먼저 헤더를 읽을 때, vector<tagS> 등을 만날 경우에도 헤더 파일에 존재하지 않는 tagS에 대해서는 일단 넘어가게 됩니다. 전방 선언을 해 줬기 때문입니다. 사용해야 하는 헤더를 cpp 파일에 숨겼기 때문에, 헤더 파일에서 불필요하게 전부 읽어들일 필요가 없어집니다.

주의할 점은 객체의 인스턴스가 아닌, 포인터만을 사용할 수 있다는 것입니다. 인스턴스를 생성하기 위해서는 클래스의 정보가 필요하기 때문에 헤더 파일이 필요합니다.

 

A.h

#pragma once

class B;	// 1. 전방 선언

class A
{
private:
	B *b;	// 2. 클래스 포인터 선언

public:
	A();

};

A.cpp

#include "A.h"
#include "B.h"	// 3. 헤더 파일 include

A::A()
{
	b = new B();	// 4. 동적 메모리 할당
}

 

반응형
복사했습니다!