#define 보다 cosnt, enum, inline
#define ASPECT_RATIO 1.653
위와 같은 ASPECT_RATIO 매크로 상수는 컴파일러가 쓰는 테이블에 포함되지 않습니다.
빌드하면 컴파일 이전에 전처리기가 매크로를 상수로 전부 바꿔버리죠.
그래서 컴파일러는 ASPECT_RATIO를 알 수 없게 됩니다.
// #define ASPECT_RATIO 1.653 // (X)
const double AspectRatio = 1.653; // (O)
이제 AspectRatio가 컴파일러 테이블에 포함되었습니다.
그리고 #define ASPECT_RATIO를 쓰지 않는 곳까지 치환되는 것을 막을 수 있어서
이전보다 파일의 크기도 작아질 수 있게 되었습니다.
const char* const CharacterName = "zozo";
책에서 문자열 포인터는 *(에스크리터) 앞 뒤로 const를 붙이라고 하는군요 !
static const 멤버 변수의 활용
클래스의 static const 멤버는 클래스 내부에 사본으로 돌려 쓸 때 좋다고 합니다.
// GameRule.h //
class GameRule
{
private:
static const int TurnCounts = 10;
int Scores[TurnCounts]; // 상수를 사용하려는 부분
};
그러나 구형 컴파일러는 위와 같은 방법이 받아들여지지 않을때가 있습니다.
// GameRule.cpp //
const int GameRule::MaxTurn;
이럴 땐 위와 같이 cpp에 정적 변수를 초기화합니다.
// GameRule.h //
class GameRule
{
private:
static const int TurnCounts;
int Scores[TurnCounts];
};
// GameRule.cpp //
const int CGameRule::MaxTurn = 10;
그런데 가~끔 여타 컴파일러에서 TurnCounts 배열의 크기를 미리 알고 싶어서
컴파일 에러가 나올 수 있다고 합니다.
여기서 #define TURNCOUNTS 10과 같은 매크로 상수로 대체했을 경우,
#undef로 유효 범위를 따로 설정하지 않는 한 캡슐화의 혜택을 받을 수 없습니다.
이럴 땐 오히려 클래스 내부에서 enum 타입을 활용하는 것이 안전합니다.
enumerator 둔갑술
enumerator 타입은 int가 놓인 곳에 쓰일 수 있다는 점을 활용합니다.
// GameRule.h //
class GameRule
{
private:
enum
{
TurnCounts = 10
};
int Scores[TurnCounts]; // 배열의 크기에 대한 컴파일 에러가 사라진다.
};
배열의 크기를 알고싶어하는 컴파일 에러가 사라졌습니다.
위에 있는 TurnCounts는 #define과 비슷하게 동작하다고 합니다.
TurnCounts를 위한 별도의 메모리를 할당하지 않아서 그런 것 같습니다.
실제로 이 방법은 템플릿 메타 프로그래밍에서 핵심 기법이라는군요.
#define 매크로 함수 대신 인라인 템플릿 함수 사용하기
함수의 호출 과정을 없애고 싶어서 아래와 같은 매크로 함수를 정의했습니다.
#define MAX_NUMBER(a,b) ((a) > (b) ? (a) : (b))
int a = 5, b = 0;
MAX_NUMBER(++a, b) // a가 두 번 증가함
MAX_NUMbER(++a, b = 999) // a가 한 번 증가함
그러나 전처리기의 단순 치환 ++ 한 번, 비교 과정 ++ 한 번으로
a가 두 번 증가해서 의도치않은 결과가 나올 수 있습니다.
이럴 땐 인라인 템플릿 함수를 활용할 수 있습니다.
진짜 함수이기 때문에 인자의 유효 범위와 규칙을 그대로 따라갑니다.
template <typename T>
inline int MaxNumber(const int& a, const int& b)
{
return (a > b ? a : b);
}
'Effective C++ 정리' 카테고리의 다른 글
06. 컴파일러가 자동으로 생성하는 함수 호출 없애기 (0) | 2019.12.20 |
---|---|
05. 컴파일러가 자동으로 생성하는 함수 (0) | 2019.12.20 |
04. 멤버 초기화 리스트 (0) | 2019.12.15 |
03. const 키워드 (0) | 2019.12.14 |
01. C++의 구성 요소 (0) | 2019.12.13 |