void SelectionSort (int *a, const int n) {
for (int i = 0; i < n; i++) {
int j = i;
for (int k = i+1; k < n; k++)
if (a[k] < a[j]) j = k;
swap(a[i], a[j])
}
}
SeletionSort 함수 코드를 예제로 살펴봅시다. (SeletionSort를 모른다면 클릭!)
위의 코드는 정수 배열 a를 정렬하는 SelectionSort로 정렬하는 프로그램입니다.
하지만, 내가 정렬하려는 배열이 int형이 아니라면? double, float등 다양한 자료형에 대해 정렬하는 프로그램이 필요하다면?
우리는 해당 자료형에 맞게 같은 코드의 함수를 인자의 자료형만 바꿔서 작성해야할 것입니다. 그렇게 된다면, 중복된 코드가 많아지면서 저장 공간이나 개발시간 등의 측면에서 효율성이 굉장히 떨어질 것입니다.
그래서 다음과 같이 자료형에 구애받지 않고 코드를 사용할 수 있도록 template함수를 도입하여 이러한 문제점을 해결하고 코드의 재사용성을 높일 수 있습니다.
template<class T>
void SelectionSort(T *a, const int n) {
for (int i = 0; i < n; i++) {
int j = i;
for (int k = i+1; k < n; k++)
if (a[k] < a[j]) j = k;
swap(a[i], a[j])
}
}
함수 정의부에는 위에 template<class T>라고 명시해준 후에, 자료형이 올 자리에 T를 적으면 됩니다.
템플릿은 함수템플릿과 클래스템플릿으로 나누기도 하는데, 함수템플릿에는 template<typename T>를, 클래스템플릿에는 template<class T>를 명시해주면 됩니다.
사용할 때에는, 다음과 같이 사용해주시면 됩니다.
float farray[2021];
int intarray[2908];
SelectionSort(farray, 2021);
SelectionSort(intarray, 2908);
그런데 만약, int형으로 오버로딩된 함수가 있다면, template함수보다 int형으로 오버로딩된 함수가 우선적으로 실행됩니다.
template함수를 우선적으로 실행하도록 다음과 같이 명시할 수 있습니다.
SelectionSort <int>(intarray,2908);
int, float의 경우 <, =, 및 복사생성자가 자동으로 정의되어있습니다.
하지만, 사용자 정의 데이터 타입에 대해서는 별도로 정의하여야 합니다.
특히, 멤버 변수로 포인터가 있는 경우 대입 연산을 하게 되면 값이 복사가 되는 것이 아니라 하나의 저장공간을 같이 가리키는 상황이 발생하게 됩니다.
이를 'shallow copy', 묵시적 구현이라고 합니다.
이 경우를 방지해주기 위해, 연산자 오버로딩을 통해 'deep copy'를 해주어야 합니다.