C ++에서 앞으로 선언이 필요한 이유
컴파일러는 철자가 틀리거나 잘못된 수의 인수를 함수에 전달하지 않도록합니다. 따라서 사용하기 전에 먼저 'add'(또는 다른 유형, 클래스 또는 함수) 선언을 볼 것을 주장합니다.
이것은 실제로 컴파일러가 코드의 유효성을 검사하는 더 나은 작업을 수행하고 느슨한 끝을 정리하여 깔끔한 모양의 객체 파일을 생성 할 수있게합니다. 선언을 전달할 필요가 없다면 컴파일러는 'add'함수가 무엇인지에 대한 모든 가능한 추측에 대한 정보를 포함해야하는 오브젝트 파일을 생성합니다. 그리고 링커가 add를 사용하여 생성하는 것과 다른 객체 파일에 'add'함수가있을 수있을 때 실제로 호출하려는 'add'를 시도하고 해결하기 위해 링커에는 매우 영리한 논리가 포함되어야합니다. dll 또는 exe. 링커에서 잘못된 추가가 발생했을 수 있습니다. int add (int a, float b)를 사용하고 싶지만 실수로 작성하는 것을 잊었지만 링커가 이미 존재하는 int add (int a, int b) 그리고 그것이 옳은 것이라고 생각하고 그것을 대신 사용했습니다. 코드가 컴파일되지만 예상 한대로 수행되지 않습니다.
따라서 명시 적으로 유지하고 추측 등을 피하기 위해 컴파일러는 사용하기 전에 모든 것을 선언해야한다고 주장합니다.
선언과 정의의 차이점
따로 선언과 정의의 차이점을 아는 것이 중요합니다. 선언은 무언가 모양을 보여주기에 충분한 코드를 제공하므로 함수의 경우 반환 유형, 호출 규칙, 메서드 이름, 인수 및 유형입니다. 그러나 메소드의 코드는 필요하지 않습니다. 정의를 위해서는 선언과 함수 코드가 필요합니다.
사전 선언으로 빌드 시간을 크게 줄일 수있는 방법
이미 함수 선언이 포함 된 헤더를 # includ'ing하여 현재 .cpp 또는 .h 파일로 함수 선언을 가져올 수 있습니다. 그러나 프로그램의 .cpp 대신 # .h에 헤더를 포함하면 # 작성하는 .h를 포함하는 모든 것이 결국 모든 헤더를 포함하므로 # 컴파일 속도가 느려질 수 있습니다 당신도 #includes를 썼습니다. 갑자기 컴파일러에는 하나 또는 두 개의 함수 만 사용하려는 경우에도 컴파일해야하는 #included 페이지 및 코드 페이지가 있습니다. 이를 피하려면, 순방향 선언을 사용하고 파일 맨 위에 함수 선언을 직접 입력하면됩니다. 함수를 몇 개만 사용하지 않으면 헤더를 포함하여 항상 # 컴파일하는 것보다 컴파일 속도가 빨라질 수 있습니다. 정말 큰 프로젝트의 경우
두 정의가 서로를 사용하는 순환 참조
또한 전진 선언을 통해주기를 중단 할 수 있습니다. 두 기능이 서로를 사용하려고하는 곳입니다. 이런 일이 발생하면 (그리고 완벽하게 유효한 일입니다) # 헤더 파일 하나를 포함시킬 수 있지만, 해당 헤더 파일은 현재 쓰고있는 헤더 파일을 #include하려고 시도합니다 .... 그런 다음 # 다른 헤더를 포함합니다 # 쓰고있는 것을 포함합니다. 각 헤더 파일이 다른 것을 #include하려고 시도하면서 닭고기와 달걀 상황에 빠졌습니다. 이를 해결하기 위해 파일 중 하나에서 필요한 부분을 전달하고 #include를 해당 파일에서 제외시킬 수 있습니다.
예 :
파일 Car.h
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Car
{
std::vector<Wheel> wheels;
};
파일 Wheel.h
흠 ... Wheel에 Car에 대한 포인터가 있기 때문에 Car의 선언이 필요하지만 컴파일러 오류가 발생할 수 있으므로 Car.h는 여기에 포함될 수 없습니다. Car.h가 포함되어 있으면 Wheel.h를 포함하는 Car.h를 포함하는 Wheel.h를 포함 시키려고 시도합니다. 이것은 영원히 계속되므로 컴파일러가 오류를 발생시킵니다. 해결책은 대신 Car 선언을 전달하는 것입니다.
class Car; // forward declaration
class Wheel
{
Car* car;
};
Wheel 클래스에 car 메소드를 호출해야하는 메소드가있는 경우 해당 메소드를 Wheel.cpp에 정의 할 수 있으며 Wheel.cpp는 이제주기를 발생시키지 않고 Car.h를 포함 할 수 있습니다.