헤더포함 의존성을 줄여줌
만약 A.h에 B.h를 추가한다면 A.h를 추가하는 모든 곳에 간접적으로 B.h도 값이 추가가 되기 때문에 코드가 굉장히 무거워질 수 있음
상호참조 에러를 방지할 수 있음
#include "B.h"
class A
{
...
};
#include "A.h"
class B
{
...
};
A클래스에 B클래스 객체 하나를 만들어 주려면 B.h를 불러와야 함
그리고 B클래스에서도 A클래스 객체를 하나 만든다면 A.h를 불러와야함
이렇게 된다면 A클래스 객체를 만드려면 A클래스의 완전한 정보가 있어야 하는데 A클래스를 보니 B클래스 객체를 만들게 되어 있어 무한하게 사이클이 돌아감
참조하려는 헤더파일(클래스)에 변경이 생겨도 헤더파일(클래스)의 재컴파일이 이루어지지 않기 때문에 효율성과 속도를 증진시키고자 사용함
//#include "ObjectA.h"
class ObjectA;
포인터 객체를 선언할 때 클래스 선언 전에 필요한 클래스를 명시해 헤더파일의 중복을 막아줌
ObjectA *objA;
//ObjectA objA;
헤더파일을 포함하지 않으니 클래스에 대한 정보가 없어 해당 객체 할당 크기를 정확히 파악할 수 없음
→ 따라서 포인터 객체만 사용 가능 (포인터 형으로 선언 시 4바이트-32bit 할당)
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);
이렇게 매개변수의 이름을 생략해서 선언할 수 있음
💡 선언과 정의의 차이점
- 선언 (declaration)
: 식별자(변수/함수 이름) 및 해당 타입의 존재를 컴파일러에 알려줌
선언하지 않고 식별자를 사용하면 컴파일러 에러 발생- 정의 (definition)
: 식별자를 실제로 구현하거나 인스턴스화(메모리 할당)
정의하지 않고 식별자를 사용하면 링커 에러 발생
class Archer;
class RangeAttack
{
public:
void SetArcher(Archer archer);
Archer GetArcher() const;
};
매개변수나 리턴 타입으로 이름만 사용될 경우 포인터형이 아닌 객체를 사용할 수 있음
함수 body와 그 함수를 호출할 경우에만 클래스의 크기가 필요하기 때문