C++를 언어들의 연합체로 바라보는 안목은 필수

▶ C

  • C++은 C를 기본으로 함

▶ 객체 지향 개념의 C+

  • 'C with Classes'에 관한 모든 것
  • 클래스(Class), 캡슐화(Encapsulation), 상속(Inheritance), 다형성(Polymorphism). 가상 함수(Virtual function)
    • 정적 바인딩: 컴파일시에 메모리를 할당 >> 일반 함수, 일반 변수 할당
    • 동적 바인딩: 런타임시에 메모리를 할당 >> 가상 함수, 변수 동적 할당
  • https://simsimjae.tistory.com/293

▶ 템플릿 C++

  • C++ 일반화 프로그래밍(Generic programming)의 일부

▶ STL

  • Standard Template Library
이것만은 잊지 말자! 
C++를 사용한 효과적인 프로그래밍 규칙은 경우에 따라 달라진다. 그 경우란, 바로 C++의 어떤 부분을 사용하느냐이다.

#define을 쓰려거든 const, enum, inline을 떠올리자

▶ #define

#define ASPECT_RATIO 1.653
  • 컴파일 전에 선행 처리자(Preprocessor)가 ASPECT_RATIO를 찾아 1.653으로 치환함
  • 따라서 컴파일러는 이것이 ASPECT_RATIO라는 것을 알 수 없음
  • 디버깅에 혼란이 올 수 있음

▶ const

const double AspectRatio = 1.653;
  • 위 문제의 해결법은 매크로 대신 상수를 쓰는 것

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

  • 상수 포인터(constant pointer) 정의
    • 상수 정의는 대게 헤더 파일에 넣어 다른 파일들이 include해서 사용
    • 포인터는 const로 선언하고, 포인터가 가리키는 대상까지 const로 선언
const char* const authorName = "Scott Meyers";
  • 클래스 상수 정의
    • 클래스 상수의 사본 개수가 1개를 넘지 못하게 하고 싶다면 정적(static) 멤버로 선언
    • #define과 달리 클래스 상수는 캡슐화 혜택을 받을 수 있음
    • 오래된 컴파일러는 아래 문법을 받아들이지 못하는 경우가 있으므로, 초기값을 상수 정의시 지정
class GamePlayer{
private:
   static const int NumTurns = 5;   // 클래스 상수 선언과 동시에 초기화
}
// 오래된 컴파일러
class GamePlayer{
private:
   static const int NumTurns;        // 정적 클래스 상수 선언, 헤더파일
}

const int GamePlayer::NumTurns = 5;  // 정적 클래스 상수 정의, 구현 파일

▶ enum

  • 컴파일러가 구식인데 클래스를 컴파일하는 도중에 클래스 상수가 필요할 때 사용
  • 'enum hack' 기법
  • #define처럼 주소를 얻어갈 수 없음
class GamePlayer {
private:
   enum { NumTurns = 5 };
   int scores[NumTurns];
}

 

 

▶ 매크로 함수

  • #define을 이용한 매크로 함수는 단점이 많음
  • 아래의 경우 비교를 통해 처리한 결과에 따라 a가 증가하는 횟수가 달라짐
#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가 한 번 증가
  • CALL_WITH_MAX(++x, y) → ((++x) > (y) ? (++x) : (y)): 비교할 때 1번, return 할 때 1번 총 2번 증가
  • CALL_WITH_MAX(++x, y + 10) ((++x) > (y + 10) ? (++x) : (y + 10)): 비교할 때 1번 증가

▶ inline

  • 매크로 함수의 문제점에 대한 해결법
  • 일반적인 함수 호출 과정을 거치지 않고, 함수의 모든 코드를 호출된 자리에 바로 삽입하는 방식
  • 함수를 호출하데 걸리는 시간이 절약됨
template<typename T>
inline void callWithMax(const T& a, const T& b)
{
   f(a > b ? a : b);
}
이것만은 잊지 말자! 
단순한 상수를 쓸 때는, #define보다 const 객체 혹은 enum을 우선 생각하자
함수처럼 쓰이는 매크로를 만들려면, #define 매크로보다 인라인 함수를 우선 생각하자

낌새만 보이면 const를 들이대 보자!
  • 값을 바꾸면 안된다면 명시적으로 const를 사용
char greeting[] = "Hello";
const char *p = greeting;   // 비상수 포인터, 상수 데이터
char * const p = greeting;  // 상수 포인터, 비상수 데이터
  • 아래 두 코드는 완전히 동일
void f1(const Widget *pw);
void f2(Widget const *pw);

+ Recent posts