3냥 집사이면서 게임 개발자입니다.
[전문가를 위한 C++] 메서드 템플릿 본문
메서드 템플릿은 클래스 템플릿 안에 정의해도 되고 비템플릿 클래스 안에 정의해도 된다.
메서드 템플릿은 클래스 템플릿에 복제 생성자와 대입 연산자를 정의할 때 특히 유용하다.
* 가상 메서드와 소멸자는 메서드 템플릿으로 만들 수 없다.
간단한 예시
Grid<int> IntGrid;
Grid<double> DoubleGrid;
이렇게 만든 두 변수는 타입이 서로 다르다.
Grid <double>객체를 받는 함수는 Grid<int> 객체를 인수로 받을 수 없다.
int 를 double로 강제 형변환해서 int원소를 double원소로 복제할 수는 있지만, 위 객체끼리는 대입하거나 변환이 불가능하다.
따라서 다음과 같이 작성하면 컴파일 오류가 발생한다.
DoubleGird = IntGrid;
이유는 Grid 템플릿에 대한 복제 생성자와 대입 연산자를 어떻게 정의했는지에서 파악해야한다.
Grid(const Grid& src);
Grid<T>& operator=(const Grid& rhs);
이를 정확히 표현하면
Grid(const Grid<T>& src);
Grid<T>& operator=(const Grid<T>& rhs);
와 같다.
그러므로 Grid<double> 을 인스턴스화해서 Grid 복제 생성자와 operator= 을 호출하면 컴파일러는 각각에 대한 프로토 타입을 다음과 같이 생성한다.
Grid(const Grid<double>& src);
Grid<double>& operator=(const Grid<double>& rhs);
생성된 Gird<double>클래스에는 Grid<int>를 받는 생성자나 operator= 이 없다.
이를 메서드 템플릿으로 서로 다른 타입을 처리할 수 있다.
// 생략
// 1.
template <typename E>
Grid(const Grid<E>& src);
// 2.
template <typename E>
Grid<T>& operator=(const Grid<E>& rhs);
void swap(Grid& other) noexcept;
// 생략
1. 템플릿 버전으로 수정한 복제 생성자
클래스는 T라는 타입에 대해 템플릿화되고, 수정한 복제 생성자는 E라는 타입에 대해 템플릿화 된다.
두 타입에 대해 템플릿화함으로써 한 타입의 Gird 객체를 다른 타입의 Grid로 복제할 수 있다.
template <typename T>
template <typename E>
Grid<T>::Grid(const Grid<E>& src) : Grid(src.getWidth(), src.getHeight())
{
// 이 생성자의 생성자 이니셜라이저는 적절한 양의 메모리를 할당하는 작업을 비복제 생성자에 위임한다.
// 그리고 나서 데이터를 복제한다.
for(size_t i = 0; i < mWidth; i++)
{
for(size_t j = 0; j < mHeight; j++)
{
mCells[i][j] = src.at(i,j);
}
}
}
복제 생성자를 정의하는 코드다.
클래스 템플릿 선언문(T 매개변수가 있는)을 먼저 적고, 그 뒤에 멤버 템플릿(E 매개변수를 가진)을 선언하는 문장을 따로 작성해야 한다. 두 문장을 합쳐서 작성하면 안된다. (template <typename T, typename E>)
2. 템플릿화한 대입 연산자는 const Grid<E>& 타입의 인수를 받아서 Grid<T>& 타입을 리턴한다.
template <typename T>
template <typename E>
Grid<T>& Grid<T>::operator=(const Grid<E>& rhs)
{
// 자기 자신을 대입할 경우에 대한 예외 처리를 할 필요가 없다.
// 이 버전의 대입 연산자는 T와 E가 같으면 호출되지 않는다.
// 복제후 바꾸기
Grid<T> temp(ths); // 모든 작업을 임시 인스턴스에서 처리
swap(temp); // noexept 키워드를 사용한 swap 함수
return *this;
}
템플릿화한 대입 연산자는 먼저 템플릿화한 복제 생성자를 이용해 Grid<E>객체를 Grid<T> 객체(temp) 로 변환한다.
그리고 swap메서드로 Grid<T> 타입인 temp 를 this와 맞바꾼다.
'CPPTMP' 카테고리의 다른 글
[전문가를 위한 C++] 클래스 템플릿 (0) | 2024.11.28 |
---|