항목2: #define을 쓰려거든 const, enum, inline을 떠올리자

2022. 6. 18. 01:48·STUDY/Effective C++

#define 소스코드의 경우에는 컴파일러에게 넘어가기 전, 선행처리자에서 숫자 상수로 바꾸어버린다.

그래서 #define pie 3.141 이라면

pie라는 이름은 컴파일러가 쓰는 기호 테이블에 들어가지 않고 숫자 상수(3.141)로 대체된다.

 

CONST

하지만 #define대신에 const를 사용해

const double pie = 3.141; 을 작성한다면 상수타입의 데이터이기 때문에 컴파일러에서도 보이게된다. 

 

그리고 매크로인 #define을 쓰게된다면 3.141의 사본이 등장횟수만큼 코드안에 들어가지만, 상수 타입인 const를 쓰면 사본이 한개만 생성되어 최종 코드의 파일 크기가 더작아지게된다. 

 

 

※ #define을 상수로 교체할때의 주의할 점

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

포인터는 꼭 const로 선언, 포인터가 가리키는 대상까지 const로 선언

const char * const alphabet = "ABCD";
const std::string alphabet = "ABCD";//위보다 더 좋은방법

 

2. 클래스 멤버로 상수를 정의하는 경우

Class GamePlayer{
private:
	static const int  NumTurns = 5; // 상수선언
	int scores[NumTurns];
	...
};

3번째 줄의 코드는 '정의'가 아닌 선언이다. 정적 멤버로 만들어지는 정수류 타입의 클래스 내부 상수는 정의 없이 선언만 해도 아무 문제없다.

const int GamePlayer::NumTurns; //NumTurns정의

하지만 컴파일러가 정의를 달라고 떼쓰는 경우에는 위와 같은 클래스 상수 정의를 '구현파일'에 둔다.

선언된 시점에서 상수의 초기값이 주어지기때문에, 정의에서는 초기값이 주어지면 안된다.

 

#define으로는 클래스 상수를 정의할 수도, 캡슐화 혜택도 받을 수 없다.

 

class CostEstimate{
private:
	static const double FudgeFactor; //정적 클래스 상수 선언(헤더파일에 두기)
	...
};
const double
	CostEstimate::FudgeFactor = 1.35; //정적 클래스 상수 정의(구현파일에 두기)

오래된 컴파일러의 경우에는 반대로 선언된 시점에서 초기값을 주는게 아닌, 정의 시점에 초기값을 주도록해야한다.

 

 

ENUM

여기서 예외)

Class GamePlayer {
private:
	enum {NumTurns = 5 }; //5에대한 기호식 이름으로 만듬
    
    int scores[NumTurns];
    ...
};

오래된 컴파일러를 배려해서 '나열자 둔갑술'(enum hack) 기법을 활용하자.

나열자 타입의 값은 int가 놓일 곳에도 쓸 수 있다. 원래라면 클래스내 초기화 금지로인해 위의 int scores[NumTurns]같은 배열멤버선언은 오래된 컴파일러에서 동작하지못한다.

 

 

INLINE

#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b)) //#define을 쓴 경우


template<typename T> //inline에 대한 Template을 쓴 경우
inline void callWithMax(const T& a, const T& b)
{
	f(a>b ? a:b);
}
CALL_WITH_MAX(++a,b);
CALL_WITH_MAX(++a,b+10);

매크로를 작성할 때는 매크로 본문에 들어 있는 인자마다 반드시 괄호를 씌워주어야한다.

하지만 inline을 쓴다면 그런 괄호들을 굳이 씌울 필요가 없다.

 

이런 눈에 보이는 부분들이 아니더라도

밑의 코드들을 보았을때 #define매크로를 사용한다면 f가 호출되기도 전에 a가 증가하는 횟수가 달라지게 된다. 

하지만 inline을 쓴다면 인자를 여러번 평가할지 모른다는 걱정도 없다.

그리고 매크로가 아닌 진짜 함수이기때문에 함수의 유효범위 및 접근규칙을 그대로 따라가기에 기존 매크로의 효율유지는 와 함께 함수의 모든 동작방식 및 타입의 안정성까지 챙길 수 있다.

 

 

 

 

'STUDY > Effective C++' 카테고리의 다른 글

항목 6: 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해버리자  (0) 2022.06.23
항목 5: C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자  (0) 2022.06.23
항목 4: 객체를 사용하기 전에 반드시 그 객체를 초기화하자  (0) 2022.06.23
항목 3: 낌새만 보이면 const를 들이대 보자!  (0) 2022.06.18
항목1: C++를 언어들의 연합체로 바라보는 안목은 필수  (0) 2022.06.13
'STUDY/Effective C++' 카테고리의 다른 글
  • 항목 5: C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자
  • 항목 4: 객체를 사용하기 전에 반드시 그 객체를 초기화하자
  • 항목 3: 낌새만 보이면 const를 들이대 보자!
  • 항목1: C++를 언어들의 연합체로 바라보는 안목은 필수
wise_
wise_
  • wise_
    WHY'S BlOG
    wise_
  • 전체
    오늘
    어제
    • 분류 전체보기 (63)
      • PROJECT (19)
        • 젯슨나노 프로젝트 (0)
        • 유니티 (9)
      • STUDY (37)
        • 코딩문제 (13)
        • 알고리즘 (0)
        • Effective C++ (14)
        • 유니티 (8)
        • 언리얼 (2)
      • ERROR (7)
        • 오류덩어리들 (7)
      • REVIEW (0)
      • LIFE (0)
        • 작고 소중한 내 일상 (0)
        • 작고 귀여운 내 취미 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    알고리즘
    퍼즐게임
    윈터데브캠프
    귀여운
    힐링게임
    여우는오늘도친구를구한다
    error
    백준
    c#
    깊이우선탐색
    힐링
    스마일게이트
    유니티
    1인개발
    C++
    모바일게임
    코딩
    게임개발
    개발
    게임
    언리얼
    개발일지
    unity
    와이즌
    인디게임
    null
    ==
    TheFoxSeeksFriend
    플로이드와샬
    wisen
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
wise_
항목2: #define을 쓰려거든 const, enum, inline을 떠올리자
상단으로

티스토리툴바