전방선언:

클래스/ 스트럭처/ 함수 등등을 구현하기 전에 미리 선언하는 방식이라고 생각하면 된다.


함수와 데이터 구조의 전방 선언 사용방식이 약간 다르다. 

주석의 번호를 따라가며 설명을 읽어보면 어느정도 그 기능의 차이에 대해 이해할 수 있을거라고 생각한다.


  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
//.1.
//.선언만 되고 정의는 되지 않은 클래스 형식.
//.선언만 된 클래스는 포인터로는 사용 가능하지만 실제 구현부의 정의가 먼저 나올때까지 기능은 사용할 수 없다.
class ForwardDec;

//.2-ⓐ
//.함수는 미리 선언만 해 두면 기능을 사용한다고 선언할 수 있다.
//.선언부가 존재한다면, 함수를 적재할 주소를 미리 지정해 둔다고 생각하면 된다.
void excution(ForwardDec * dec);
void excution2(ForwardDec * dec);
int main()
{
ForwardDec * dec;
//.2-ⓑ
//,소스코드 순서상에서 아직 정의가 없는 상태라고 볼 수 있지만,
//.함수는 런타임에서 실행되고, 런타임 상에서는 미리 정해진 메모리의 주소에 함수를 실행하는 코드부분이 적재되어 있기 때문에
//.함수의 실행 자체는 큰 문제가 없다.
excution(dec);
}

void excution(ForwardDec * dec)
{
//. 3
//. 이 시점에서, PrintLove함수는 존재하지 않는다.
//. 컴파일러는 단지 FowardDec 클래스가 존재한다는 사실,
//. 그리고 그 포인터가 존재한다는 사실만을 알고 있기 때문에, 실제 구현부에 있는 함수는 사용할 수 없다.
//. 3-ⓐ
//.따라서 다음과 같은 시행은 문제가 발생한다. (함수에 부여할 메모리 주소가 정해지지 않았는데 먼저 사용함.)
dec->PrintLove();//->(오류 발생)
//. 3-ⓑ
//. 로컬 변수로도 선언할 수 없다. (어떤 형태를 가지는 클래스인지 알수 없음.)
ForwardDec dec2;//->(오류 발생)
//. 3-ⓒ
//. 단, 전방선언 이후 클래스 정의 이후에 다시 정의되는 함수의 경우에는 정상적으로 작동한다.
excution2(dec);//-> (정상 작동)
}
//. 4
//. 헤더파일에는 클래스의 정의가 들어있다. 아래 주석의 내용이 이자리에서 선언되었다고 생각하면 된다.
#include "forwardDec.h"
/*
// #include <iostream>
//
// class ForwardDec
// {
// public:
// void PrintLove()
// {
// std::cout << "LOVE";
// }
// };
*/
void excution2(ForwardDec * dec)
{
//. ⑤
//. 이제 정의가 등장했으니 컴파일러는 FowardDec 이 어떤 클래스인지 잘 알고있다.
//. 로컬 변수와 함수를 시행 가능하므로 포인터를 넘겨받아 사용 가능해졌다.
dec->PrintLove();//-> (정상 작동)
ForwardDec dec2;//-> (정상 작동)
}




간단히 요약.


클래스의 전방 선언은 해당 클래스의 포인터를 통해 자료형에 맞는 데이터를 미리 적재할 수 있게 도와준다.

단, 내용 자체가 모두 선언된것이 아니고 이러한 자료형이 있다~ 정도만 알려주는 것이므로 포인터만 활용 가능하고,

 포인터를 통해 함수 시행, 변수 값 변경 등은 불가능하다.

하지만 클래스를 사용하겟답시고 클래스를 사용하는 모든 소스파일에 해당 클래스의 정의문을 헤더 파일 include를 강제하는 현상을 억제하여

결과적으로 소스의 컴파일 타임을 줄여준다.("include"로 집어넣는 것들은.. 그 파일에 해당하는 텍스트를 복붙해 준다고 이해하면 편하다)


함수의 전방 선언은 함수를 부를 수 있는 주소를 미리 지정해 두고 필요한 곳에서 선언할 수 있게 도와준다.

부르는 주소만 지정해 두기 때문에 구현부의 위치는 큰 상관이 없다.

+ Recent posts