2007년 04월 03일
[C++]2. #define을 쓰려거든 const, enum, inline을 떠올리자(1)
가급적 전처리자 보다 컴파일러를 더 가까이하자.
아래코드를 보면
#define CIRCLE_RATIO 3.1415
우리에겐 CIRCLE_RATIO 가 기호식이름(symbolic name) 으로 보이지만 소스코드가 컴파일러에게 넘어가기
전에 전처리자가 숫자 상수로 바꾸어 버리기 때문에 컴파일러의 Symbol Table 에 들어가지 않는다.
그래서 에러 발생시 메시지엔 CIRCLE_RATIO가 아닌 3.1415가 있어 사용자를 헷갈리게 할 수 가 있다.
이 문제의 해결 방법으로는 Macro 대신 상수를 쓰는 것이다.
const double CircleRatio = 3.1415 ;// 대문자로만 표기하는 이름은 대게 Macro 에서만 사용언어차원에서 지원하는 상수 데이터 값이기 때문에 컴파일러의 눈에도 보이고 Symbol Table에도 들어간다
또한 이유는 Macro 를 쓰면 코드에 매칭되는 모든 곳에 3.1415로 바꾸게 되지만, 상수 타입은 아무리 여러 번
쓰더라도 사본은 딱 하나만 생기기 때문에 최종코드의 크기가 작아진다
#define 을 상수로 교체할 때의 유의 사항
1.상수 포인터 ( constant pointer ) 를 정의 하는 경우
상수 정의는 대게 Header 파일에 넣고 다른 소스 파일이 include 해서 쓰게 되므로 Pointer 는
꼭 const로 선언해주고 아울러 포인터가 가리키는 대상도 const 로 선언하는 것이 보통이다.
const char* const autorName = "Scott Meyers";
하지만 C++ 에서는 string 객체가 있으므로 다음의 선언이 더 권장된다.
const std::string authorName ( "Scott Meyers" );
2.클래스 멤버로 상수를 정의하는 경우
어떤 상수의 유효범위를 클래스로 한정하고 싶을 때 그 상수를 멤버로 만들어야 하는데
그 상수의 사본 개수가 한 개를 넘지 않게 하려면 정적( static ) 멤버로 만들어야 한다.
/* in GamPlayer.h */위의 NumTurns는 선언(declaration) 된 것이다. 정의 (definition) 이 아님을 유의하자.
class GamePlayer {
private:
static const int NumTurns = 5; // 상수 선언
int scores[NumTurns]; // 상수를 사용하는 부분
…
};
C++ 에서는 사용하고자 하는 것에 대해 정의(definition) 가 마련되어야 하는 것이 보통이지만
정적 멤버로 만들어 지는 정수류 ( 각종 정수 타입, char, bool 등 ) 타입의 클래스 상수는 예외이다.
이들에 대해 주소를 취하지 않는 한 , 정의 없이 선언만 해도 아무 문제가 없다 .
하지만 정의를 해달라고 닥달하는 구닥다리 컴파일러의 경우는
/* in GamPlayer.cpp */#define 은 일단 정의 되면 컴파일이 끝날 때 까지 유효하기 때문에 클래스 상수를 선언하는 데에는
const int GamePlayer::NumTurns;
// 정의에 값이 없는 이유는 클래스 상수의 초기값은 해당 상수가 선언된 시점에 바로 주어지기 때문
쓸 수도 없고 어떤 형태의 캡슐화 혜택도 받을 수가 없다.
오래된 컴파일러는 위의 문법이 먹히지 않는 경우가 있는데 그때는
/* in CostEstimate.h */
class CostEstimate {
private:
static const double FudgeFactor; // 정적 클래스 상수의 선언
…
};
/* in CostEstimate.cpp */
const double CostEstimate::FudgeFactor = 1.35; // 정적 클래스 상수의 정의
# by | 2007/04/03 11:54 | Effective C++ | 트랙백(1)





제목 : 항목 31 : 이상한 코드 ( 난이도 : 4 )
이번 항목에서 말하고자 하는 것을 정확히 겪어 본 터라, 책의 예제는 생략하고, 경험담만 쓰려고 한다. 이번 항목은 #define 의 단점을 정확히 지적을 한다. 경험 1. 졸업 작품 만드는 중 KGCA15기 동기인 강일이형이 "도저히 디버깅을 할 수가 없는데, 좀 봐봐" 라고 하면서 코드를 보여 줬다. 이상이 없는 코드인데, 컴파일이 되지 않는 것이 문제점이 였다. 에러 메세지를 봐도, "이 문구의 에러가 아닌데 왜 이러는거야!" 라고 속으로......more