C++에서 미리 함수를 정의하지 않으면 순차적으로 코드를 읽어들여 오류를 발생시킨다. (식별자 찾을 수 없음)
그러나 전방선언이 이뤄졌다면 컴파일러는 오류 없이 지나간다.
C++ 전방선언 (Forward Declaration)
식별자를 정의하기 전 식별자의 존재를 컴파일러에 미리 알리는 것
필요에 따라 함수, 변수, 클래스 등을 전방선언한다.
컴파일 시간을 단축시킨다.
헤더포함 의존성을 줄여준다.
int x; //선언
x = 42; //x를 사용
C++ 클래스 전방선언
헤더파일에서 헤더파일을 포함시키는 행위는 컴파일 시간을 증가시킨다. (하나의 헤더파일이 변경되어도 include한 파일들이 모두 재컴파일)
// #include "ObjectA.h" 생략하고
class ObjectA; //클래스 전방선언
그래서 포인터 객체를 선언할 때 클래스 선언 전에 필요한 클래스를 명시해 헤더파일의 중복을 막아주는 것이다.
- C++ 클래스 전방선언은 헤더포함 의존성을 최소화
- 해당 헤더의 불필요한 정보 비노출
ObjectA *objA;
// ObjectA objA; //불가능
이렇게 사용하는데 헤더파일을 포함하지 않으니 클래스에 대한 정보가 없어서
포인터 객체만 사용 가능하다.
단, 전방 선언을 사용할 경우, 전방선언한 클래스에 대한 객체는 포인터형으로 선언해야 한다.
(
해당 객체 할당 크기를 정확히 파악할 수 없어서이며 포인터형으로 선언 시 4바이트(32bit OS에서)를 할당)
Mother* m_pMainFamily = nullptr;
C++ 함수 전방선언
함수의 몸체를 정의하기 전 함수의 존재를 컴파일러에 미리 알리는 것을 말한다.
함수 전방선언 방법은 함수 원형 (함수 선언문)을 사용하여 작성하면 된다.
그러면 리턴타입, 이름, 매개변수는 들어가지만 함수 몸체는 포함하지 않고 명령문이므로 세미콜론으로 끝난다.
#include <iostream>
int add(int x, int y); //전방선언
int main()
{
...
add(3, 4);
return 0;
}
int add(int x, int y) //정의
{
return x+y;
}
사용은 이런 식으로 한다. 함수 원형에서 매개변수의 이름을 생략해서 선언할 수도 있다.
int add(int, int); // 전방선언 이렇게도 가능
C++ 선언과 정의의 차이점
- 선언 (declaration) : 식별자(변수/함수이름) 및 해당타입의 존재를 컴파일러에 알려준다.
선언하지 않고 식별자를 사용하면 컴파일러에서 에러가 발생한다.
- 정의 (definition) : 식별자를 실제로 구현하거나 인스턴스화(메모리 할당) 한다.
정의하지 않고 식별자를 사용하면 링커에서 에러가 발생한다.
- C++에서 모든 정의는 선언으로도 간주한다. (int x;)
대부분은 정의만 필요하나 정의되기 전에 식별자를 사용해야 한다면 명시적인 선언이 필요하다.
C++ 매개변수 / 리턴 타입을 위한 이름만 참조하는 전방선언
함수의 매개변수나 리턴 타입으로 이름만 사용될 경우 포인터형이 아닌 객체를 사용할 수 있다.
함수 body 와 그 함수를 호출할 경우에만 클래스의 크기가 필요하기 때문이다.
// 전방선언
class Archer;
class RangeAttack
{
public:
void SetArcher(Archer archer);
Archer GetArcher() const;
참고한 곳
- https://boycoding.tistory.com/143
- 3
- http://egloos.zum.com/sweeper/v/2827565
'C, C++' 카테고리의 다른 글
[C++] 비주얼스튜디오 함수에서 참조되는 확인할 수 없는 외부 기호 오류 (0) | 2021.11.22 |
---|---|
[공유] [C/C++] 구문 오류 : ';'이(가) '*' 앞에 없습니다 (0) | 2021.11.22 |
[C, C++] Doxygen 설치와 작성 방법, Graphviz 설치까지 (0) | 2021.11.09 |
[C, C++] 주석 종류 모음, 비주얼스튜디오 주석 단축키 (0) | 2021.11.09 |
가상함수 테이블 (0) | 2021.11.01 |