Adaid's Workroom

[EC++] 1-2. #define을 쓰려거든 const, enum, inline을 떠올리자 본문

서적 공부/Effective C++

[EC++] 1-2. #define을 쓰려거든 const, enum, inline을 떠올리자

어데이드 2017. 12. 12. 22:49

1장: C++에 왔으면 C++의 법을 따릅시다


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

(=가급적 선행 처리자보다 컴파일러를 더 가까이하자)


이유

선행처리자가 소스코드를 컴파일러에게 넘어가기 전에 숫자 상수로 바꾸어버림

-> 숫자 상수로 대체된 코드에서 컴파일 에러 발생 시 헷갈릴 수 있음


대신 const(상수) 이용


상수 사용시 이점

컴파일러도 알 수 있음, 기호 테이블에 들어감

상수가 부동 소수점 실수 타입이면 최종 코드 크기가 더 작아질 수 있음


상수 사용시 주의점

1.  상수 포인터 정의

상수 정의는 대개 해더 파일에 넣는 것이 상례

포인터와 더불어 포인터가 가리키는 대상까지 const로 선언하는 것이 보통

(ex) const char * const authorName = "Scott Meyers";

*문자열 상수는 string 객체로 쓰는 것이 좋음

(ex) const std::string authorName("Scott Meyers");


2. 클래스 상수 정의

상수 사본 개수가 한 개를 넘지 못하게 하고 싶다면 정적(static) 멤버로 만들어야 함

(ex)

class GamePlayer {

private:

static const int NumTurns = 5;

...

}

여기서 NumTurns는 정의X, 선언된 것

정적 멤버로 만들어지는 정수류 타입의 클래스 내부 상수는 정의가 없어도 됨

단 클래스 상수의 주소를 구하거나 할 때는 별도의 정의 필요

(ex) const int GamePlayer::NumTurns;

이때 클래스 상수 정의는 해더 파일X, 구현 파일에 둔다

클래스 상수의 초기값은 해당 상수가 선언될 당시에 바로 초기화 되므로 정의에는 상수의 초기값이 있으면 안됨

* 오래된 컴파일러는 초기값을 정의 시점에 주도록 한다


오용: 매크로 함수

(ex)

#define CALL_WITH_MAX(a, b) f( (a) > (b) ? (a) : (b) )


int a = 5, b = 0;

CALL_WITH_MAX(++a, b);            //a가 두번 증가

CALL_WITH_MAX(++a, b+10);       //a가 한 번 증가


매크로 함수 대신 인라인 함수에 대한 템플릿 이용

-> 기존 매크로의 효율 유지, 정규 함수 동작방식 및 타입 안전성 취함


(ex)

templete<typename T>

inline void callWithmax(const T& a, const T& b)

{

f(a > b ? a : b);

}

Comments