가능한 한 include 대신 포워드 선언을 사용해야합니까?
아니요, 명시적인 전방 선언은 일반적인 지침으로 간주되어서는 안됩니다. 포워드 선언은 본질적으로 복사하여 붙여 넣거나 철자가 틀린 코드로, 버그를 발견 한 경우 포워드 선언이 사용되는 모든 곳에서 수정해야합니다. 이는 오류가 발생하기 쉽습니다.
"앞으로"선언과 해당 정의 사이의 불일치를 방지하려면 선언을 헤더 파일에 넣고 해당 헤더 파일을 정의 및 선언 사용 소스 파일 모두에 포함합니다.
그러나 불투명 한 클래스 만 포워드 선언되는이 특별한 경우에는이 포워드 선언을 사용해도 괜찮지 만, 일반적으로이 스레드의 제목처럼 "가능하면 항상 포함 대신 포워드 선언을 사용"할 수 있습니다. 꽤 위험합니다.
다음은 전방 선언과 관련된 "보이지 않는 위험"의 몇 가지 예입니다 (보이지 않는 위험 = 컴파일러 또는 링커에서 감지하지 않는 선언 불일치).
아래의 예는이를 보여줍니다. 예를 들어, 데이터와 함수의 두 가지 위험한 전방 선언이 있습니다.
파일 ac :
#include <iostream>
char data[128][1024];
extern "C" void function(short truncated, const char* forgotten) {
std::cout << "truncated=" << std::hex << truncated
<< ", forgotten=\"" << forgotten << "\"\n";
}
파일 bc :
#include <iostream>
extern char data[1280][1024];
extern "C" void function(int tooLarge);
int main() {
function(0x1234abcd);
std::cout << "accessing data[1270][1023]\n";
return (int) data[1270][1023];
}
g ++ 4.7.1로 프로그램 컴파일 :
> g++ -Wall -pedantic -ansi a.c b.c
참고 : g ++는 컴파일러 또는 링커 오류 / 경고를 제공하지 않으므로 보이지 않는 위험입니다.
참고 : 생략 하면 C ++ 이름 변경으로 인해 extern "C"
연결 오류가 function()
발생합니다.
프로그램 실행 :
> ./a.out
truncated=abcd, forgotten="♀♥♂☺☻"
accessing data[1270][1023]
Segmentation fault