[C++]2. #define을 쓰려거든 const, enum, inline을 떠올리자(2)

나열자 둔갑술 ( enum hack )

클래스 상수의 초기값을 상수의 정의 시점에 둘 때 한가지 예외가 있다.
해당 클래스를 컴파일 하는 도중에 상수의 값이 필요한 때가 그때이다.

/* in GamePlayer.h */
class GamePLayer{
private:
    int scores[NumTurns]; //이와 같은 경우

};

컴파일러는 컴파일 과정에서 이 배열의 크기를 알아 내야 하는데 정수 타입의 정적
클래스 상수에 대한 클래스 초기화를 금지하는(표준에 어긋난 구식이지만) 구식 컴파일러의
대처 방법으로 나열자 둔갑술을 사용할 수 있다

/* in GamePlayer.h */
class GamePLayer{
private:
enum { NumTurns = 5 ; } //통칭 나열자 둔갑술
    int scores[NumTurns]; //해결!

};

나열자 둔갑술의 특징
1. 동작 방식이 const보다는 #define에 더 가깝다
// const 의 주소를 얻는 것은 합당하나 enum 의 주소를 얻는 것은 합당하지 않다.
2. 어떤 형태의 쓸데없는 메모리 할당을 하지 않는다.
3. 많은 코드에서 이 기법이 사용되고 있다


Macro 함수 보다는 inline 함수를 사용하자

#define CALL_WITH_MAX( a, b ) f( (a) > (b) ? (a) : (b) ) //A와B중 큰 것을 f에 넘겨 호출
Macro작성시 기본적으로 괄호를 씌어 주어야 하나 이것으로 끝나는 것이 아니다

int a = 5, b = 0;

CALL_WITH_MAX( ++a, b ); //a가 두 번 증가합니다
CALL_WITH_MAX( ++a, b+10 ); //a 가 한 번 증가합니다

위와 같은 사태를 막기 위해서 inline 함수에 대한 Template 만들어 준다.

template<typename T>    //T가 정확히 무엇인지 모르기 때문에
inline void callWithMax( const T& a, const T& b ) //매개변수로 상수 객체의 참조자를 쓴다
{
       f( a > b ? a : b );
}

이 함수는 템플릿이기 때문에 동일 계열 함수군(family of functions : 하나의 템플릿을 통해
만들어 질 것으로 예측 가능한 모든 함수들을 통칭)을 만들어 낸다.

by 일찍자라 | 2007/04/03 14:41 | Effective C++ | 트랙백

◀ 이전 페이지          다음 페이지 ▶