본문 바로가기
C,C++/Error & Warning

[C++] LNK2019, LNK1120 클래스 템플릿 사용 시 링크 오류

by woohyeon 2019. 11. 28.
반응형

클래스 구현 도중 틀린 건 없는데 아래 에러가 계속 발생하였다.

LNK2019, LNK1120


https://docs.microsoft.com/ko-kr/cpp/error-messages/tool-errors/linker-tools-error-lnk2019?view=vs-2019

 

결론 먼저 말하면 클래스 템플릿은 헤더와 소스를 분리하면 안되고 그 선언과 구현(정의)을 같은 파일(.h)에 해야 한다. 

나는 헤더 파일과 소스 파일을 따로 작성하였는데 main 함수가 있는 소스파일에서 헤더파일만 include 했더니 제대로 참조를 하지 못했다.

그 이유를 살펴보면 우선 우리가 클래스 템플릿가 아닌 일반 클래스의 선언과 구현을 헤더와 소스 파일에 분리하여 작성했다고 생각해 보자. 그리고 main에서 해당 클래스를 사용하기 위해 헤더 파일을 인클루드 했다. 여기서 컴파일을 하면 컴파일러는 main.cpp를 컴파일해 줄 것이다. 그런데 main 함수에서 해당 클래스를 사용한다. 다행히 컴파일러는 해당 클래스에 대한 정보를 인클루드된 헤더 파일을 통해서 얻을 수 있다. 그러나 선언에 대한 정보만 있을 뿐 구현에 대한 정보는 없다. 하지만 타입들은 이미 정해졌으므로 임시적으로 컴파일해 줄 수 있다. 대신 이처럼 컴파일된 파일(.obj)들을 서로 연결시킬 때(link) 그 구현체를 찾을 수 있어야 한다. 만약 구현체를 찾으면 성공적으로 하나의 실행 파일을 만들어준다. 

그런데 클래스 템플릿은 이게 왜 안될까? 클래스 템플릿 또는 함수 템플릿은 inline 함수와 비슷하게 컴파일 시간에 그 구현체를 찾을 수 있어야 한다. 만약 main.cpp에서 Func<int>(a, b)를 호출 했다면 컴파일러는 컴파일 시간에 Func<T> 함수의 정의를 찾아 타입만 int로 변경해서 코드를 그대로 복붙해 주어야 한다. 그런데 선언부만 포함된 헤더 파일만 포함하게 되면 컴파일 시간에 코드를 복붙해 줄 수가 없다. 따라서 위와 같은 에러를 뱉는다.




댓글