C++.8 template

lsw·2021년 4월 9일
0

C++

목록 보기
8/8
post-thumbnail

1. 템플릿이란..

같은 내용을 담고있는(기능을 수행하는) 함수라고 해도 반환형, 매개변수형(입력 인자형)에 따라 다른 함수가 될 수 있다. 마찬가지 클래스도 멤버 내 변수, 함수 형에 따라 같은이름의 다른 클래스가 될 수 있다. 이 때 같은기능을 하는 함수 및 클래스를 한번만 정의하되 서로 다른 형(type)을 입력, 반환(클래스 정의, 멤버 변수, 함수 정의 시 반환형, 매개변수형, 인자형...etc) 하고자 할 때 템플릿을 사용한다.


2. 템플릿의 기본 구조

  • 함수 템플릿
#include <iostream>
using namespace std;

// 템플릿 인자인 T1, T2. 두 개의 형변수(type variables)를 둘 수 있고 디폴트값 또한 지정 가능 
template <typename T1, typename T2=void> // T2의 디폴트값은 void 이다. 
T2 Swap(T1 param1, T1 param2)
{
    T1 param3 = param1;
    param1 = param2;
    param2 = param3;
}

int main()
{
   int num1=5, num2=6;
   Swap<int>(num1, num2); 
// 함수 템플릿을 호출하면 컴파일러에 인식된 형에(typename) 맞는 템플릿 함수를 임시생성한다.
/* 함수 호출시와 마찬가지로 좌측 매개변수부터 복사가 된다. 따라서 T1=int로 초기화 되고 T2는
   디폴트값인 void로 초기화 된다. 이때 컴파일러는 입력 인자인 num1, num2의 형이 int임에 T1이 
   int임을 미루어 짐작할 수 있다. <int>를 생략할 수 있다는 말!!
*/
   cout << "num1 = " << num1 << "\nnum2 = " <<  num2 << endl; 
// Swap 함수 정상작동(excution) 확인
}

자세한 설명은 주석 참조

  • 클래스 템플릿
template <typename T>
class Point
{
    T xpos, ypos;
    public:
    Point(T x, T y)
    void Show()
{
   cout << xpos << ypos << endl;
}
};

int main()
{
// 이 역시나 클래스 템플릿 호출 시 **임시 템플릿 클래스를 생성하여 객체를 생성한다.** 
   Point <int> pos1(3,5); 
   Point <char> pos2 = {'a', 'b'};
   Point <double> pos3 = {0.05, 0.01};
// 클래스에선 '<>' 부분을 생략할 수 없다. 반드시 명시해야 함
   return 0;
}

3. 응용 - 배열 클래스 템플릿

배열클래스는 정의 시 반환형에 따라(변수원형인지, 포인터형인지, 더블포인터형인지) 여러개의 함수를 생성해야 했는데 이번기회에 템플릿을 통해 이를 하나로 통합하여 보자.

#include "Point.h" // Point class 참조
#include <iostream>
using namespace std;

typedef Point * POINT_PTR // Point클래스의 포인터형 이름을 POINT_PTR로 정의(typedef)
template <class T>
class arrayclass
{
   T * arr;
   int arrlen;
// 배열의 고유성을 위해 복사생성자, 대입연산자에는 private 접근성을 부여한다.
   arrayclass(arrayclass & acopy);
   arrayclass & operator=(arrayclass & acopy);
public:
    arrayclass(int len=0):arrlen(len)
{
   arr = new T[len]
}
    T & operator[](int idx)
{
   if(idx <0 || idx >= arrlen)
  {
     cout << "out of range" << endl;
     exit(1);
  }
   return arr[idx];
}
// 기타 함수 생략...
};

이에 대한 실전문제 적용은 Bank account ver.6에서 다뤄보자.


4. 몇가지 규칙

  1. 함수
  • 템플릿 함수를 생성할 때 컴파일러 입장에서(그 입장이 어떤 것인지는 위 코드설명에서 확인 가능!) 인자형이 명백히 주어진다면 별도의 ""선언은 생략할 수 있다.
  • 한 번 생성된 템플릿 함수는 main함수가 반환(종료)될 때까지 별도공간에 남아있기(임시생성 상태로) 때문에 동일한 형의 템플릿 함수를 재정의 할 필요가 없다.
  • 템플릿 매개변수 정의 시 선언문으로 'typename' , 'class' 모두 사용 가능하며 뒤의 고유문자도 마찬가지 무엇이든 가능하다.
  1. 클래스
  • 템플릿 클래스는 어떠한 경우에서도 별도""선언을 통해 typename 을 밝혀야 한다. (인자가 몇개가 되었건 간에 모두 채워줘야 한다.)
  • 클래스 템플릿 시 함수를 선언 - 정의부로 나누고자 한다면 정의부에서 하나의 함수를 정의할 때마다
template <typename T> 
/* 선언부의 클래스템플릿과 동일한 선언문자, 문자 사용. 
   단, 아래 함수정의에서 **미지변수 T가 필요한 경우에만** 해당하며 T가 필요 없을 시
   template<> 로 써준다.
*/
type classname<T>::functionname(factor1, factor2, ...)

의 방식대로 함수를 정의하여야 한다.

  • 템플릿은 위와같이 선언 - 정의부를 나눈 후 해당하는 클래스를 참조하기 위해서 헤더파일은 물론, 클래스 정의가 담겨있는 소스파일(cpp)도 함께 참조 해줘야 한다.(include)
#include "arrayclass.h"
#include "arrayclass.cpp"
// 이하 헤더파일 중략...

int main()
{
   arrayclass <Point> arc1; 
// 이처럼 **템플릿클래스**를 생성하고자 한다면 분리된 소스파일도 참조해야 한다.
   arrayclass <POINT_PTR> arc2;
// ..생략...
}

5. 느낀점

함수 템플릿 - 템플릿 함수 / 클래스 템플릿 - 템플릿 클래스의 1. 사용법 2. 사용 경우 3. 규칙 에 관하여 알게 되었다. bank account 프로젝트에 적용해 보자.

profile
미생 개발자

0개의 댓글