프로그래밍/cpp

클래스 템플릿에 대한 이해 C++

콘파냐 2014. 6. 17. 17:41
반응형

클래스 템플릿도 함수 템플릿과 비슷합니다. 


알고리즘이 동일하다는 조건하에 


멤버들의 다른 경우 템플릿으로 해결할 수 있습니다. 


템플릿 함수를 이해했다면 이해하기 쉽기 때문에 


긴말 없이 예제로 바로 들어 가겠습니다.




결과는 1이 찍히는 간단한 프로그램입니다. 함수 템플릿과 동일하게 template <typename T>로 시작합니다. 클래스의 선언부를 선언하는 방식은 기존 클래스 문법과 똑같습니다. 호출에 따라 달라질 멤버변수만 T로 선언해 주면 됩니다. 객체의 생성시 클래스명 뒤에는 <타입명>을 적어주도록 합니다. 클래스의 경우는 함수와 달리 이렇게 명시적으로 클래스를 호출해주어야 합니다. 단, 함수 템플릿의 경우도 인수로 타입네임이 정해지지 않은 경우에 명시적 호출을 하는 것과 비교해서 이해해 주시길 바랍니다. 참고로 생성자에 타입네임을 인수로 사용할 경우에도 객체생성시 클래스명 뒤에<typename>을 붙여야 합니다. 생성자를 호출하기 전에 클래스 객체의 크기가 몇인지 알고 메모리를 할당해야 하기 때문에, 생성자를 통해 T의 타입이 무엇인지 아는 것은 의미가 없습니다. 


21째줄 부터는 외부에 클래스멤버를 작성한 것입니다. 이를 위해서 클래스 템플릿의 멤버임을 알리기 위해 template <typename T> 가 와야 하고 클래스명에 <T>가 붙어야 합니다.


템플릿 함수는 호출 시에 컴파일러에 의해서 작성됩니다. 마찬가지로 템플릿 클래스는 객체의 생성시에 전달된 타입에 맞는 클래스를 구체화합니다. 



템플릿 클래스의 상속

class A : class MyClass<int> {

private:

~~

public:

~~

};


템플릿 클래스가 구체화 되는 시점은 클래스의 객체가 생성될 때라고 했습니다. 단, 템플릿 클래스를 다른 클래스가 상속 받은 경우 컴파일러는 객체의 생성유무를 떠나서 구체화합니다.


멤버함수의 템플릿화




클래스 템플릿 모듈화

연습이 아니라면 모듈화는 필수기 때문에 모듈화를 하는데 필요한 개념들을 설명하겠습니다. 이 부분은 기존에 간략히 설명해 놓은 포스팅이 있지만, 실습에 있어서 중요한 부분이기 때문에 다시 복습하겠습니다.


2014/01/24 - [프로그래밍/C언어] - 분할컴파일 하는법(gcc) c언어


A클래스를 선언할 A.h, A클래스의 멤버의 정의 A.cpp, 메인이 되는 main.cpp 세개의 파일을 작성합니다.




위 예는 간단한 모듈화 프로그래밍입니다. 여기에 A클래스를 템플릿으로 바꾸어 선언해보겠습니다. 그리고 실행해보았습니다.


에러가 나는군요.

멤버함수 print()의 정의가 되지 않았다고 합니다. 하지만 클래스 템플릿으로 바꾸기전에는 컴파일과 실행이 제대로 되었습니다. 문법적인 에러는 없습니다. 이렇게 에러가 나는 현상은 템플릿의 속성을 제대로 알고 이해해야 합니다.

일반적인 클래스의 경우에는 아무 에러없이 컴파일 실행이 되는 이유는 컴파일->링크 라는 일련의 과정중 컴파일 과정에 그 원인이 있습니다. 

템플릿의 구체화 시점 -> 컴파일시

일반적인 함수는 컴파일시 원형선언만 있으면 됨->링크시 바인딩

다시말해 템플릿은 컴파일 시점에 구체화가 되어야 하기 때문에, 헤더파일에 모든 정의가 되어 있어야 합니다. A.cpp로 부터 만들어지는 A.o 목적파일은 링크시 바인딩되기 때문에 컴파일러는 멤버함수를 찾을 수 없다는 에러를 냅니다. 당연히 멤버함수의 정의는 A.o에 들어있고 컴파일시에는 알수 없고, 링크시에 알수 있기 때문입니다.



이렇게 헤더파일이 정의부를 구현해주면 문제없이 해결됩니다. 

정리하면 클래스 템플릿의 멤버함수의 정의부 구현은 헤더파일에 모두 합니다. 이렇게 하는 이유는 템플릿이 컴파일시 구체화를 하는 특징 때문입니다.'로 정리해 두면 되겠습니다.

반응형