.CDst.h_________
#include "CSrc.h"
class CDst{
CSrc m_Src;
}
.CSrc.h_________
#include "CDst.h"
class CSrc{
CDst m_Dst;
}
두개의 다른 파일이 서로를 ‘순환하여’ 참조하며, 객체를 포함하고 있을 때 원칙적으로 컴파일러가 메모리 계산을 할 수가 없게 됨. (데스트 포함 → 소스 포함- > 데스트 포함 → … 무한 루프)
그렇기에 사용하고자 하는 자료형을 먼저 선두에 알려주는 문법이 나타나는데, 이것이 전방 선언이다.
.CDst.h_________
#include "CSrc.h"
class CDst{
CSrc* m_Src;
}
.CSrc.h_________
class CDst;
class CSrc{
CDst* m_Dst;
}
전방 선언은 자료형의 유무만 판단, 멤버 변수의 종류, 크기 , 함수의 형식을 알 수가 없다. 그렇기에 생성자 함수를 호출할 수가 없다.
그렇기에, 계속해서 Class를 멤버로 가지고 있게 되면 지속적으로 컴파일러는 메모리의 크기를 계산하려고 한다.
따라서!
- 메모리의 크기가 정해진 포인터 타입(8바이트)만을 선언해야 한다.
- 헤더 파일의 전방선언은 헤더에만 해당 존재를 알려주기 때문에 해당 클래스 cpp 파일에 상호 참조하는 자료형의 헤더파일을 포함해야 한다.
- 대신 한쪽 클래스에만 적용해도 문제가 없다.
주의하라!
상호 참조하고 있는 객체들끼리 생성자 내에서 동적할당을 하게 되면
B생성단계->A생성자 호출->A생성 단계->B생성자 호출 -> B생성 단계 -> .....
무한루프가 돌아감. 그렇기에 생성자에서 생성자를 부르고, 소멸자에서 소멸자를 부르는 것은 매우 위험하다! 그렇기에 Initialize를 사용하는 것이다.
전방선언 남발은 라이브러리 파일을 비대하기 만들기 때문에 좋지 않다.
—피드백— 전방선언은 사실 권장되는 문법이다. 헤더 파일 안에 헤더파일들을 만들게 되면 헤더간의 종속성이 비대화되며 컴파일 타임이 늘어나게 된다.
또한, 컴파일 이후 링크 과정에서 헤더 파일간의 종속성을 나타내는 자료가 함께 첨부되기 때문에 오히여 라이브러리 파일이 더욱 커지게 된다.
확인완료 피드백이 사실로 확인됨. 실제 테스트해본 결과 3천키로바이트와 6천키로바이트로 굉장히 큰 차이가 나타난 것을 확인함(헤더 1개 차이임에도 불구)