ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 템플릿(template)
    플밍/C++ (overview) 2012. 1. 3. 23:19
    2006/08/31 21:41



    템플릿이란?

     

    템플릿은 본을 뜨기위한 '틀'이다!

    다양한 재료를 넣고 여러번 쓸수 있도록 만들어졌다.

     

    다음과 같이 사용한다.

     

    template <typename T>  

    add(T a, T b){

           ...

    }

     

    'typename' 대신 'class'를 써도 무방하다.

    타입을 T로 치환했으면 typename T라고 쓰면 된다. (T말고 딴걸로 해도 된다.)

     

    T가 결정되는 시점은, 저 함수가 호출되는 시점, 좀더 정확히는 인자가 전달되는 순간이다.

     

    ========================================================================================

     

    함수 템플릿

     

    (함수 템플릿과 템플릿 함수는 다르다. 지금 얘기하고자 하는것은 템플릿이긴 템플릿인데

    함수의 꼴을 하고 있는 템플릿이다.)

     

    1. 둘 이상의 타입에 대해 템플릿화 하기

     

    template <typename T1,....., typename T2>

    void fun(T1 a, T2 b){

           ...

    }

     

    T1과 T2는 서로 다른 타입이라는 것을 말해주고 있지만, 같은 타입이어도 상관없다.

     

    2. 함수 템플릿의 특수화

     

    전달되는 타입에 따라 각기 다른 일을 하도록 하고 싶다면, 특수화 시켜라.

     

    template <typename T>

    int SizeOf(T a){

           return sizeof(a);

    }

     

    template<>                  // 특수화된 함수임을 선언

    int SizeOf(char* a){

           return strlen(a);

    }

     

    SizeOf에 전달되는 인자가 char* 타입일때는 밑의 함수가 호출된다.

     

    밑의(특성화된) 함수는 한줄로 나타낼수도 있는데,

     

    template<> int SizeOf<char*>(char* a) 이것이 원형이고,

    template<> int SizeOf<>(char* a) 이것이 조금 생략된 형태이고,

    template<> int SizeOf(char* a) 이것이 가장 간단한 형태이다.

     

    ========================================================================================

     

    클래스 템플릿

     

    1. 함수 템플릿과 마찬가지이다.

     

    template <typename T>

    class AAA{

           치환하고자 하는걸 T로 모두 바꿈.

    };

     

    main(){

           AAA<int> a1(..);

           AAA<char> a2(..);

    }

     

    굵게표시한 부분을 눈여겨보자.

    클래스 템플릿을 객체화 할때는 왜 자료형을 명시해줘야 할까?

    매개변수를 받았을때 초기화할수도 있을텐데, 왜 굳이 미리 써줘야 하는걸까?

     

    객체의 생성과정을 생각해보면 쉽다.

    매개변수의 정보를 넘기려면 생성자를 호출해야 하는데, 그 전에 먼저 거쳐야 하는 것이

    메모리 할당이다.

    객체에 적당한 메모리 공간을 할당해야 하는데, 생성자도 호출되지 않아서 무엇이 넘어올지

    모르는데, T를 뭐라고 생각하고 메모리 할당을 하겠는가?

     

    <* 사실 더 중요한 이유가 있다. 생성자를 통해 전달되는 인자와, 결정되어야 할 템플릿의

    자료형이 일치 하지 않을수도 있기때문이다. 즉, 생성자를 통해 전달되는 인자가 템플릿의

    자료형이라고 볼수는 없다. >

     

    2. 클래스 템플릿의 선언과 정의 분리

     

    template <typename T>

    class AAA{

            T data;

    public:

            Data(T d);

            T GetData();

    };

     

    template <typename T>

    AAA<T>::Data(T d){

           ...

    }

     

    template <typename T>

    AAA<T>::GetData(){

           ...

    }

     

    사용법을 눈여겨 보자. AAA<T>라고 적지 않고, AAA라고 하면 보통의 AAA의 함수를 정의하는

    꼴이 된다. 그리고 template임을 선언하는 template <typename T>를 꼭 붙여주어야 한다.

     

    3. 스택의 template화

     

    자주 사용하는 자료구조와 알고리즘을 template으로 정의해놓으면 여러모로 유용할것이다.

    실제로 이미 전문가들에 의해서 이러한 일들은 진행되어 왔으며, 이러한 template의 모음을

    가리켜 STL(Standard Template Library) 라고 한다.

     

    ========================================================================================

     

    템플릿의 원리 이해

     

    template <typename T>

    T add(T a, T b){

           return a+b;

    }

     

    이런 template은 호출 가능한 함수가 아니다! 호출가능한 함수를 만들기 위한 '틀'에 불과하다.

     

    main(){

           add(10, 20);

           add(1.2, 2.3);

    }

     

    이렇게 호출을 하게 되면, 컴파일러에 의해서 첫번째 문장은

     

    int add(int a, int b){

           return a+b;

    }

     

    두번째 문장은,

     

    double add(double a, double b){

           return a+b;

    }

     

    이런 함수를 만들게 된다.

     

    이렇게 '틀'(template)로 찍어낸 함수를 가리켜 템플릿 함수 라고 한다.

    그리고 이 과정을 가리켜 "함수 템플릿의 인스턴스화(instantiation)" 라고 한다.

     

    클래스 템플릿도 마찬가지이다. 클래스 템플릿은 객체화가 가능한 클래스를 만들기 위한

    하나의 '틀'에 불과하다.

    함수 템플릿과 템플릿 함수, 클래스 템플릿과 템플릿 클래스는 같은 관계이다.

     

    이상의 과정을 다시 살펴보면, 함수 템플릿은 함수 오버로딩과 비슷하단 생각이 들지 않는가?

     

    이처럼, 템플릿을 처리하는것은 컴파일러이기 때문에 클래스 템플릿은 선언과 정의를 각각

    다른파일(헤더와 몸체)로 분리시켜 놓을수 없다. 분리된것의 연관관계를 찾아주는것은

    컴파일러가 아닌 '링커' 이기 때문이다.

    따라서, 클래스 템플릿은 하나의 파일 내에 선언과, 정의가 함께 있어야 한다.

    '플밍 > C++ (overview)' 카테고리의 다른 글

    예외 처리  (0) 2012.01.03
    string 클래스 디자인  (0) 2012.01.03
    연산자 오버로딩  (0) 2012.01.03
    virtual 응용(원리, 다중상속)  (0) 2012.01.03
    상속(심화), 두종류binding, virtual  (0) 2012.01.03
Designed by Tistory.