[Effective C++] 항목 2 : #define을 쓰려거든 const, enum, inline을 떠올리자

수민이슈·2023년 3월 13일
0

Effective C++

목록 보기
2/30
post-thumbnail

스콧 마이어스의 Effective C++을 읽고 개인 공부 목적으로 요약 작성한 글입니다!

💡 단순한 상수를 쓸 때는 #define보다 const 객체, 혹은 enum을 우선 생각하자!
💡 함수처럼 쓰이는 매크로를 만들려면, #define 매크로보다 인라인 함수를 우선 생각하자!

🖊️ 매크로를 피해야 하는 이유

#define ASPECT_RATIO 1.653					// - A
		
const double AspectRatio = 1.653;			// - B

A의 경우

컴파일러에게 넘어가기 전 선행처리자가 밀어버리고 숫자 상수로 변경

문제점

  • ASPECT_RAIO는 컴파일러가 쓰는 기호 테이블에 들어가지 않는다
    -> 기호식 디버거에 나타나지 않음
  • 코드에서 ASPECT_RATIO는 1.653으로 모두 변경됨 -> 1.653의 사본이 등장 횟수만큼 생성됨
    -> 최종 코드의 크기가 커질 수 있음

따라서

B : 매크로 대신 상수로 쓰는 경우!

1.653의 사본은 딱 한 번만 생김 -> 최종 코드의 크기가 작아진다
기호 테이블에 들어가고, 기호식 디버거에 나타난다 (디버깅시 확인 가능)

상수 정의 시 주의해야할 부분

1. 상수 포인터를 정의하는 경우

포인터와 포인터가 가리키는 대상까지 const로 선언해줘야 한다!
-> const를 2번 써야 한다

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의 차이점도 알아봐야겠다.

0개의 댓글