안녕하세요. 제프입니다. 오랜만에 인사드리네요.
요즘 날씨가 너무 더워 회사에서도 그동안 안틀던 에어컨이 빵빵하게 나와서 열심히 일에 몰두하느라 강좌가 많이 늦었습니다. ^^;
그럼 바로 강좌를 시작해보도록 하겠습니다. 지금 찾아주신 이곳은 크리티 프로젝트의 시작 Zeprod.org 입니다.
오늘 알려드릴 내용은 바로 템플릿입니다. 이번에 배우실 내용인 템플릿은 C++만의 특징이라고 할만큼 독특한 문법입니다.
이는 C언어, 자바는 물론 어느 언어를 보더라도 이런 개념을 도입한 언어를 찾아보기 힘들정도로 C++ 그 자체에 특화된 문법이라고 할 수 있습니다.
템플릿은 클래스, 함수등의 선언시에 사용되는 키워드로써 사용되는 위치는 typedef와 비슷합니다. 그럼 예제를 보시죠.
template class A {
// 클래스 설계 및 구현
T m_data;
public:
A () {};
~A () {};
T get_Data () { return m_data; }
}
클래스 선언부에 템플릿을 적용한 부분입니다. 이것이 템플릿을 사용하기위한 전부입니다. 이렇게 간단하게 템플릿을 통해 클래스를 선언하면 아래와 같이 활용이 가능합니다.
A a;
이렇게 템플릿에서 로 사용된 부분에 타입을 넣어주시면 해당 템플릿 내의 모든 T가 해당 타입으로 지정되어 선언됩니다.
또한 get_Data처럼 내부에 지정된 함수에도 템플릿이 지정되어 해당 타입의 변수를 리턴할 수 있습니다.
즉, 위에서 a로 선언된 객체는 int 형의 m_data를 인자로 갖게 됩니다. 이렇게 한가지 클래스를 만들어놓고 다양한 타입에 적용될 수 있도록 한 것이 바로 템플릿입니다.
이 템플릿에는 포인터, 변수, 클래스 등등 모든 타입이 지정될 수 있어, 이것으로인해 C++만의 확장성이 드러나게 됩니다.
아직 그 편리함을 잘 모르시겠다구요?
일전에 여러분께서는 연결리스트 클래스를 만드신적이 있습니다. 그 리스트에는 오직 int형만 보관할 수 있었죠.
바로 그 클래스를 템플릿을 적용하도록 조금만 바꿔준다면 아래와 같은 응용도 가능합니다.
list a;
list b;
list c;
list d;
같은코드라도 템플릿을 이용하는 것만으로 아래와 같이 타입별로 저장할 데이터 형식을 지정해줄수도 있도록 확장성을 지니게 된 것이죠.
정말 편리하겠죠? C++ 표준 라이브러리는 대부분 이렇게 템플릿을 이용해 정의가 되어 있어서 사람들이 어떤 클래스를 만들었다고 하더라도 그 라이브러리를 문제없이 이용할 수 있도록 하고 있습니다.
우리가 만들었던 연결리스트도 바로 표준라이브러리 내에 이미 만들어져 있죠. 물론 템플릿이 적용된 상태로 말이죠. 이런 표준 라이브러리를 바로 STL이라고 합니다.
include
void main()
{
list a;
}
STL내에는 우리가 만들었던 리스트는 물론, 동적인 크기를 가진 배열인 vector, 스택과 큐의 특성을 모두 가진 dequeue, 정렬을 최대한 효율적으로 하기위한 set, 가장 빠른 검색 능력을 가진 map 등이 구현되어 있으며, 문자열을 관리할 수 있는 string 등의 데이터를 보관하는 클래스 등 그 외에도 다양한 라이브러리가 숨겨져 있습니다.
이런 내용은 MSDN을 찾아보시면 금방 알아보실 수 있을 겁니다만, STL에 대한 내용만으로도 지금까지 C++에 대한 강좌를 쓴것보다 더 많은 내용이 필요하므로 이번에는 이쯤에서 멈추도록 하겠습니다.
이쯤하면 템플릿의 확장성에 대해 어느정도 느낌을 잡으셨으리라고 생각합니다. 사실 적용방법이 그렇게 어렵지 않으면서도 이정도의 메리트를 느낄 수 있다는 것이 바로 템플릿의 장점이 아닌가 합니다.
또 한가지 템플릿을 이용해 조금 놀라운 장난을 보여드릴텐데요. 템플릿이 컴파일을 하면서 각 데이터형에 맞는 함수들을 직접 생성하는 방법을 사용하는 것을 응용한 방법입니다.
template struct Fibo
{
enum { value = Fibo + Fibo }
}
template <> struct Fibo<1> { enum { value = 1 } }
template <> struct Fibo<0> { enum { value = 1 } }
템플릿을 함수처럼 사용한것이 보이시나요?
같은 식이죠. 이렇게 선언해놓고 다음과 같이 사용하면, 컴파일러가 컴파일을 수행하면서 템플릿을 실제 데이터에 맞게 변경하면서 아예 상수로 변경되어 버립니다. 바로 아래와 같이요.
int i = Fibo<10>::value; // -> int i = 55 // 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
int j = Fibo; // 프로그램 에러
일단 예를 들어본것은 피보나치 수열을 구하는 것입니다. 이것을 실제 함수로 만들어서 실행한다면 프로그램이 계산을 해야겠지만,
이렇게 템플릿을 이용해 값을 구해내면 컴파일 시점에 이미 결과가 정해져 버렸기 때문에 단순하게 변수를 대입하는 수준으로 그칠것입니다.
당연히 실행속도가 빠른것은 두말할 것도 없죠. 대신 단점은 항상 변하지 않는 상수를 사용하여야만 컴파일러가 미리 계산을 할 수 있다는 것이고, 만약 변수를 템플릿에 넣는다면 프로그램이 죽어버리게 됩니다.
만약 구동중에 바뀌는 변수를 이용한 연산이 아니라면 이런방법도 사용할만 합니다.
다만, 템플릿 메타 프로그래밍은 아직 시작된 역사가 짧아 컴파일러가 지원하는 범위가 좁습니다.
재귀적으로 계산할 수 있는 계산에도 한계가 있고, 컴파일러가 계산하는 것이므로 컴파일러에 따른 제한이 있다는 점이 문제이죠.
그런점만 유의하신다면, 아니 이런 방식이 아닌 템플릿 자체의 기능만으로도 충분히 제역할을 할 것이라고 생각합니다.
이제 마지막 인사를 드릴 시간이로군요. 이전 강좌에서 GUI 프로그래밍을 알려드린다고 했었는데 잘 생각해보니 C++ 자체에 대한 강좌인 이곳에는 맞지 않는것 같아 이렇게 C++의 마지막 요소인 템플릿을 설명드리게 되었습니다.
그래서 이번편 템플릿을 마지막으로 'C++의 사용법을 알아봅시다.'는 이만 끝을 낼까 합니다.
대략적인 문법설명과 객체지향에 대한 개념설명, 그리고 이번에 설명해드릴 템플릿을 모두 아신다면, C++ 언어 자체에 대한 내용은 모두 배우셨다고 보셔도 됩니다.
이제는 그 C++을 활용해 어떻게 효율적인 프로그래밍을 할 수 있는가에대한 내용을 배우셔야할 차례죠.
다음 강좌부터는 주제를 바꿔 C++과 WinAPI를 이용해 최초 윈도우 화면을 띄우고 어떻게 다루는 것인지에 대한 설명을 해드릴까 합니다.
주제가 바뀌는만큼 언제 강좌가 시작될지는 모르지만, 곧 찾아뵙도록 하겠습니다.
그럼 다음강좌도 많은 호응 보내주시고, 여러분께서도 더욱 높은 실력을 쌓으시길 바라겠습니다. 지금까지 읽어주셔서 감사합니다.