스콧 마이어스의 Effective C++을 읽고 개인 공부 목적으로 요약 작성한 글입니다!
💡 단순한 상수를 쓸 때는 #define보다 const 객체, 혹은 enum을 우선 생각하자!
💡 함수처럼 쓰이는 매크로를 만들려면, #define 매크로보다 인라인 함수를 우선 생각하자!
#define ASPECT_RATIO 1.653 // - A
const double AspectRatio = 1.653; // - B
컴파일러에게 넘어가기 전 선행처리자가 밀어버리고 숫자 상수로 변경
문제점
B : 매크로 대신 상수로 쓰는 경우!
1.653의 사본은 딱 한 번만 생김 -> 최종 코드의 크기가 작아진다
기호 테이블에 들어가고, 기호식 디버거에 나타난다 (디버깅시 확인 가능)
포인터와 포인터가 가리키는 대상까지 const로 선언해줘야 한다!
-> const를 2번 써야 한다
어떤 상수의 유효범위를 클래스로 한정하고자 할 때는 그 상수를 멤버로 만들어야 한다.
그 상수의 사본 개수가 한 개를 넘지 못하게 하고 싶다면? static 멤버로 만들어야 한다.
// 헤더파일
class GamePlayer {
private:
static const int NumTurns = 5; // 상수 선언 (정의 X)
int scores[NumTurns]; // 상수 사용
}
// cpp
const int GamePlayer::NumTurns; // 정의
사실 정적 멤버로 만들어지는 정수 타입의 클래스 내부 상수는 정의 안해줘도 되긴 함
but 정의를 꼭 해줘야 하는 상황?
클래스 상수의 정의는 cpp에 둔다.
정의 시 상수의 초기값이 있으면 안됨 -> 클래스 상수는 생성과 동시에 초기화되기 때문
class GamePlayer {
private:
enum { NumTurns = 5 }; // 나열자 둔갑술
int scores{ NumTurns };
}
enum 타입의 값은 int가 놓일 자리에 쓸 수 있다.
클래스에서 배열 멤버를 선언할 때, 컴파일 중에 클래스 상수의 값이 필요함
-> enum 타입의 변수로 돌려막기
함수 호출 오버헤드를 일으키지 않도록 매크로 함수를 사용하는 경우가 있다.
// a와 b 중 더 큰 것을 f에 넘겨 호출하는 매크로함수
#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))
int a = 5, b = 0;
CALL_WITH_MAX(++a, b); // a가 더 큼 -> a 2번 호출 -> a 2번 증가
CALL_WITH_MAX(++a, b + 10); // b가 더 큼 -> a 1번 호출 -> a 1번 증가
이런 적폐 상황이 발생할 수 있다....
이를 해결하기 위해 템플릿 인라인 함수를 만들면 된당!
template<typename T>
inline void CallWithMax(const T& a, const T& b) {
f(a > b ? a : b);
}
장점
#define을 진짜 완전 남발했는데,, 겜서버하면서 왜 이렇게 선언했지 ? 싶었는데
그걸 왜 이렇게 했는지 알겠다! 속이 다 시원하다
const와 constexpr의 차이점도 알아봐야겠다.