전방선언은 실제로 식별자(함수, 변수, 객체)
등을 정의하기 전에 식별자의 존재를 컴파일러에게 알려주는 것이다.
C++에서 헤더파일
과 cpp파일
을 분리한 후에 헤더파일
에서 먼저 선언을 해주고 cpp파일
에서 정의를 하는 것도 이러한 것이라고 볼 수 있다.
헤더파일
에다가 헤더파일
을 include시킨다면 코드를 그대로 복붙하는 것이기 때문에 별로 좋지 않다.
만약 Item
, Inventory
라는 클래스가 있을 때
Inventory
에 Item
이라는 클래스를 사용해야 한다면 include "Item.h"를 해줘야 할 것이다.
하지만 우리가 Inventory
에서 Item클래스
를 포인터형
으로 가르키고 있다면 Item클래스
라고 포인터가 주장하는 것이기 때문에 위에 class Item
으로 Item클래스
가 있다고 전방선언
을 해주는 것이다.
왜냐하면 여기서 포인터는 Item
의 세부적인 코드들을 물어보는 것이아니라
어떤식으로 메모리를 구조를 잡아야 하는지 물어보는 것이다.
그래서 "나중에 Item클래스
가 나오니까 연결해봐!" 라고 알려주는 것이다.
하지만 이렇게만 해서 끝나는 것이 아니다.
cpp파일에서 진짜 Item
을 사용하는 코드가 있다면 오류가 난다.
왜냐하면 앞에서 실제 Item형
을 사용하기 위해서는 Item클래스
의 세부적인 것들을 알아야 하기때문에 cpp파일
에서는 include "Item.h"를 해줘야 한다.
그래서 정리를 해보자면
실제로 클래스에서 다른 클래스를 당장 사용할 필요가 없다고 하면 클래스를 전방선언해서 "이 클래스가 등장 할 것이다!"이라고 알려주고 cpp에다가 include해준다.
만약 Inventory.h에 Item.h에 추가한다면 Inventory.h를 추가하는 모든 곳에 간접적으로 Item.h도 같이 추가가 되기 때문에 코드가 굉장히 무거워질 수 있다.
만약 A클래스
와 B클래스
가 있다면 A클래스
에 B클래스
객체하나를 만들어 주려면 B.h를 불러와야 할 것이다. 하지만 B클래스
에서도 A클래스
객체를 하나 만든다면 A.h를 불러와야 할 것이다.
하지만 이렇게 된다면 A클래스
객체를 만드려면 A클래스
의 완전한 정보가 있어야 하는데 A클래스
를 보니 B클래스
객체를 만들게 되어 있어 무한하게 사이클이 돌아간다.
이 상황이야 말로 "닭이 먼저냐 알이 먼저냐"하는 상황인 것 같다. 닭이 있으면 알이 있어야 하고 알이 있으면 닭이 있어야 하는 상황이 되기 때문에 문제가 생긴다.
앞으로 코딩할 때 이런걸 생각하고 해야겠다.