제공: 한빛 네트워크
저자: 최흥배
이전기사:
함수 템플릿
두 값을 비교하는 함수를 만들어야 됩니다.
HP를 비교하는 두 개의 int 타입을 비교하는 Max라는 이름의 함수를 하나 만들었습니다.int Max( int a, int b );
일을 다 끝낸 후 다음 기획서를 보니 캐릭터와 NPC가 전투를 하는 것을 구현해야 되는데
여기에는 경험치를 비교하는 기능이 필요합니다.
구현해야 되는 것은 위에서 만든 Max 함수와 같습니다. 그래서 그것을 사용하였습니다.
< List 1 >
#include앗, 체력(HP)을 저장하는 변수의 타입은 int인데, 경험치를 저장하는 변수의 타입은 int가 아닌 float 타입니다.using namespace std; int Max( int a, int b ) { return a > b ? a : b; } void main() { int Char1_HP = 300; int Char2_HP = 400; int MaxCharHP = Max( Char1_HP, Char2_HP ); cout << "HP 중 가장 큰 값은" << MaxCharHP << "입니다." << endl << endl; float Char1_Exp = 250.0f; float Char2_Exp = 250.57f; float MaxCharExp = Max( Char1_Exp, Char2_Exp ); cout << "경험치 중 가장 큰 값은" << MaxCharExp << "입니다." << endl << endl; }
당연하게 경험치를 비교하는 부분은 버그가 있습니다.
앞에 만들었던 Max와는 다르게 비교하는 변수의 타입이 float인 것이 필요하여 새로 만들었습니다.
< List 2 >
float Max( float a, float b )
{
return a > b ? a : b;
}
함수 오버로딩에 의해 경험치를 비교할 때는 int 타입의 Max가 아닌 - 의 float 타입을 비교하는 Max가 호출되어 버그가 사라지게 되었습니다.
이제 경험치 비교는 끝나서 다음 기획서에 있는 것을 구현해야 합니다.
이번에는 돈을 비교하는 것이 있습니다. 그런데 돈을 저장하는 변수의 타입은 __int64입니다.
__int64는 비주얼 C++에서만 사용할 수 있는 64비트 정수 타입입니다.
__int64 타입을 비교하는 것은 앞에서 만든 int 타입의 Max나 float 타입의 Max로 할 수 없습니다.
함수에서 사용하는 변수의 타입만 다를 뿐 똑같은 것을 또 만들어야 됩니다.
__int64 Max(__int64 a, __int64 b )
{
return a > b ? a : b;
}
현재까지만 하더라도 이미 똑같은 로직으로 구현된 함수를 3개나 만들었는데, 게임에서 사용하는 캐릭터의 정보는 HP, 경험치, 돈 이외에도 더 많습니다. 저는 앞으로 Max 함수를 몇 개 더 만들어야 할지 모릅니다. Max 함수의 구현을 고쳐야 한다면 모든 Max 함수를 찾아야 합니다. 함수 오버로딩은 문제를 해결하지만, 코드가 커지고 유지보수는 어렵게 만듭니다.
프로그래밍에서 유지보수는 아주 중요합니다. 왜냐하면, 프로그래밍은 언제나 변경이 가해지기 때문입니다. 유지보수를 편하게 하는 가장 간단한 방법은 유지보수 할 것을 줄이는 것입니다.
Max 함수를 하나로 만들고 싶습니다. 어떻게 해야 될까요?
앗, 혹시 모른다고요? 제가 이 앞에 템플릿에 대해 설명을 할 때 이런 말을 하지 않았나요?'템플릿을 사용하면 타입에 제약을 받지 않는 로직을 기술 할 수 있습니다'
네, 템플릿을 사용하면 됩니다.
함수 템플릿 Max를 만들자
아래의 코드는 템플릿을 사용하여 Max 함수를 구현 한 것입니다.
< List 3 >
#include실행한 결과는 다음과 같습니다.using namespace std; // 템플릿으로 만든 값을 비교하는 Max 함수 template T Max(T a, T b ) { return a > b ? a : b; } void main() { int Char1_HP = 300; int Char2_HP = 400; int MaxCharHP = Max( Char1_HP, Char2_HP ); cout << "HP 중 가장 큰 값은" << MaxCharHP << "입니다." << endl << endl; float Char1_Exp = 250.0f; float Char2_Exp = 250.57f; float MaxCharExp = Max( Char1_Exp, Char2_Exp ); cout << "경험치 중 가장 큰 값은" << MaxCharExp << "입니다." << endl << endl; }
네 이번에는 경험치 비교가 정확하게 이루어졌습니다.
템플릿을 사용하게 되어 이제는 불필요한 Max 함수를 만들지 않아도 됩니다..
<List 3> 코드에서 template으로 만든 함수를 '함수 템플릿'이라고 합니다.
함수 템플릿을 정의하는 방법은 아래와 같습니다.
...
함수 템플릿과 컴파일
하나의 Max 함수 템플릿을 만들었는데 어떻게 int 타입의 Max와 float 타입의 Max를 사용할 수 있을까요? 비밀은 컴파일하는 과정에 있습니다. 컴파일할 때 템플릿으로 만든 것은 템플릿으로 만든 함수를 호출하는 부분에서 평가합니다. 가상 함수처럼 실행시간에 평가하는 것이 아닙니다.컴파일을 할 때(compile time) 함수 템플릿을 평가하므로 프로그램의 성능에 해가 되는 것은 없습니다.
...
#includeusing namespace std; /* int Max( int a, int b ) { return a > b ? a : b; } float Max( float a, float b ) { return a > b ? a : b; } __int64 Max(__int64 a, __int64 b ) { return a > b ? a : b; } */ template T Max( T a, T b) { return a>b ? a : b; } void main() { int Char1_HP = 300; int Char2_HP = 400; int MaxCharHP = Max( Char1_HP, Char2_HP ); cout << "HP 중 가장 큰 값은" << MaxCharHP << "입니다." << endl << endl; float Char1_Exp = 250.0f; float Char2_Exp = 250.57f; float MaxCharExp = Max( Char1_Exp, Char2_Exp ); cout << "경험치 중 가장 큰 값은" << MaxCharExp << "입니다." << endl << endl; }
Max 함수 템플릿에 개선점이 없을까요?
힌트를 드린다면 Max의 두 인자 값은 함수 내부에서 변경되지 않습니다. 그리고 인자의 타입은 C++의기본형뿐만이 아닌 크기가 큰 타입을 사용할 수도 있습니다.
생각나셨나요? C++ 기초 공부를 차근차근 쌓아 올린 분이라면 알아차렸으리라 생각합니다.
정답은 Max 함수 템플릿을 만들 때 템플릿의 인자에 const와 참조를 사용하는 것입니다. Max 함수는 함수의 내부에서 함수의 인자를 변경하지 않습니다. 그러니 함수에 const를 사용하여
내부에서 변경하는 것을 명시적으로 막고 Max 함수를 사용하는 사람에게 알리는 역할을 합니다.
C++에서 함수 인자의 전달을 빠르게 하는 방법은 참조로 전달하는 것입니다.
위의 Max 함수는 int나 float 같은 크기가 작은 타입을 사용하였기 때문에 참조로 전달하는 것이
큰 의미는 없지만, 만약 구조체나 클래스로 만들어진 크기가 큰 변수를 사용할 때는 참조로 전달하는 것이
훨씬 빠릅니다. 앞에 만든 Max 함수 템플릿을 const와 참조를 사용하는 것으로 바꾸어 보았습니다.
template <typename T>
함수 템플릿의 전문화 라는 것이 있습니다.
Max(int, double)을 사용하면 Max 함수 템플릿이 아닌 이것에 맞는, 특별하게 만든 함수를 사용하도록 합니다. 함수 템플릿의 전문화(Specialization)라는 특별한 상황에 맞는 함수를 만들면 함수 오버로드와 같이 컴파일러가 상황에 맞는 함수를 선택하도록 합니다.< List 8 >
#includeusing namespace std; // 템플릿으로만든값을비교하는Max 함수 template <typename T1, typename T2> const T1& Max(const T1& a, const T2& b ) { cout << "Max(const T& a, const T& b) 템플릿 버전 사용" << endl; return a > b ? a : b; } // 전문화시킨Max 함수 template <> const double& Max(const double& a, const double& b) { cout << "Max(const double& a, const double& b) 전문화 버전 사용" << endl; return a > b ? a : b; } void main() { double Char1_MP = 300; double Char1_SP = 400.25; double MaxValue1 = Max( Char1_MP, Char1_SP ); cout << "MP와 SP 중 가장 큰 값은" << MaxValue1 << "입니다." << endl << endl; int Char2_MP = 300; double Char2_SP = 400.25; double MaxValue2 = Max( Char2_MP, Char2_SP ); cout << "MP와 SP 중 가장 큰 값은" << MaxValue2 << "입니다." << endl << endl; } 위 코드를 실행한 결과는 아래와 같습니다.
'온라인게임 > stl' 카테고리의 다른 글
Standard Template Library (STL), 1 of n (0) | 2010.10.07 |
---|---|
클래스 템플릿 2-2 (0) | 2010.10.01 |
STL이 무엇인지 알고 계십니까? 1 (0) | 2010.10.01 |