"가급적 전처리기보다 컴파일러를 더 가까이 하자"
#define ASPECT_RATIO 1.653
이런 경우 숫자 상수로 대체된 코드에서 컴파일 에러라도 발생하게 되면 꽤나 헷갈릴 수 있습니다.
소스 코드엔 분명히 ASPECT_RATIO가 있었는데 에러 메시지엔 1.653으로 나오기 때문에 헷갈릴 수 있습니다.
const double AspectRatio = 1.653;
매크로를 쓰면 코드에 ASPECT_RATIO가 등장하기만 하면 전처리기에 의해 1.653으로 모두바뀌면서 결국 Object Code 에서 1.653의 사본이 등장 횟수만큼 들어가게 되지만, 상수 타입의 AspectRatio는 아무리 여러 번 쓰이더라도 사본은 딱 한 개만 생기기 떄문입니다.
여기까지 정리하자면,
해당 매크로가 많이 사용된다면, 상수를 쓰는 게 맞는 것 같습니다. 그러나, 해당 매크로가 1,2 번 내 쓰인다면 매크로를 사용해도 무방하지 않을까 싶습니다.
사본 개수가 한 개를 넘지 못하게 하고 싶다면 정적 멤버로 만들어야합니다.
class GamePlayer {
private:
static const int NumTurns = 5; // 상수 선언
int scores[NumTurns];
...
}
NumTurns는 '선언'된 것입니다. '정의'가 아니니 주의하세요.
아래 코드를 보면, 왜 선언이고 정의가 아닌지 이해할 수 있습니다.
#include <iostream>
static const int d = 0;
int main(void)
{
int a = 0;
static int b = 0;
static const int c = 0;
std::cout << "test" << std::endl;
return 0;
}
a 만 디버깅에서 확인할 수 있습니다.
아마 해당 변수를 사용또는 참조할 때, 잡히는 것으로 보아 해당 시점이 정의가 아닐까 라는 생각이 듭니다.
상수 대신 enum 타입을 사용하는 방법도 있습니다!
그러나 enum을 사용하는 방식은 #define에 더 가깝습니다.
class GamePlayer{
private:
enum {NumTurns = 5};
int scores[NumTurns];
...
};
함수처럼 쓰이는 매크로를 만들려면, #define 매크로보다 인라인 함수를 우선 생각합시다.
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))
template<typename T>
inline void callWithMax(const T& a, const T& b)
{
f(a > b ? a: b);
}
'서적 > Effective C++' 카테고리의 다른 글
항목 35: 가상함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자 (0) | 2022.04.07 |
---|---|
항목 34: 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자 (0) | 2022.04.07 |
항목 33: 상속된 이름을 숨기는 일은 피하자 (0) | 2022.04.07 |
항목 32: Public 상속 모형은 반드시 "is-a"를 따르도록 만들자 (0) | 2022.04.07 |
항목 1: C++를 언어들의 연합체로 바라보는 안목은 필수 (0) | 2022.01.26 |