[E-Z] cpp01

01. C++은 μ–Έμ–΄λ“€μ˜ 연합체이닀.

c++은 크게 4κ°€μ§€ μ–Έμ–΄μ˜ 연합체이고, μ–΄λ–€ 뢀뢄을 μ‚¬μš©ν•˜λŠλƒμ— 따라 ν”„λ‘œκ·Έλž˜λ° κ·œμΉ™μ΄ λ‹€λ₯΄λ‹€.

01. c
02. 객체 μ§€ν–₯ κ°œλ…μ˜ c++

classλ₯Ό μ“°λŠ” c

03. template c++

c++의 μΌλ°˜ν™” ν”„λ‘œκ·Έλž˜λ°

04. STL

template library


02. #define λ³΄λ‹€λŠ” const, enum, inline이 μ’‹λ‹€.

λ‹¨μˆœν•œ μƒμˆ˜λ₯Ό μ“Έ λ•ŒλŠ”, 맀크둜 λŒ€μ‹  const 객체 λ˜λŠ” enumλ₯Ό μ“΄λ‹€.

issue 숫자 μƒμˆ˜λ‘œ λŒ€μ²΄λœ μ½”λ“œμ—μ„œ 컴파일 μ—λŸ¬λΌλ„ λ°œμƒν•˜λ©΄ ν—·κ°ˆλ¦°λ‹€.

#define PI 3.14

μ†ŒμŠ€μ½”λ“œκ°€ μ»΄νŒŒμΌλŸ¬μ—κ²Œ PIλ₯Ό μ•Œλ €μ£ΌκΈ° 전에, μ„ ν–‰ μ²˜λ¦¬μžκ°€ 숫자 μƒμˆ˜λ‘œ λŒ€μ²΄ν•΄λ²„λ¦¬λ―€λ‘œ μ»΄νŒŒμΌλŸ¬λŠ” PIκ°€ μ•„λ‹ˆλΌ 3.14둜 μΈμ‹ν•œλ‹€. 즉, PIλŠ” 컴파일러의 기호 ν…Œμ΄λΈ”μ— λ“€μ–΄κ°€μ§€ μ•ŠλŠ”λ‹€.

Solution λ‹¨μˆœν•œ μƒμˆ˜λ₯Ό μ“Έ λ•ŒλŠ”, 맀크둜 λŒ€μ‹  const 객체 λ˜λŠ” enumλ₯Ό μ“΄λ‹€.

const double pi=3.14;

μ»΄νŒŒμΌμ„ 거친 μ΅œμ’… μ½”λ“œμ˜ 크기가 맀크둜λ₯Ό μ‚¬μš©ν•  λ•Œλ³΄λ‹€ 더 μž‘λ‹€.
μ™œλƒν•˜λ©΄ μ „μžλŠ” PIλ§ˆλ‹€ 3.14둜 λ°”κΏ”μ€˜μ„œ λ“±μž₯횟수만큼 3.14의 사본이 ν•„μš”ν•˜μ§€λ§Œ, ν›„μžλŠ” 사본이 pi 1개면 되기 λ•Œλ¬Έμ΄λ‹€.

caution μƒμˆ˜ 포인터λ₯Ό μ •μ˜ν•  λ•Œ const μ“°μž
포인터와 포인터가 κ°€λ¦¬ν‚€λŠ” λŒ€μƒ λ‘˜ λ‹€ const둜 μ„ μ–Έν•œλ‹€.

const char* const name = "Larvine Kim"; //const std::string name = "Larvine Kim";

caution 클래슀 μƒμˆ˜λ₯Ό μ •μ˜ν•  λ•Œ μƒμˆ˜μ˜ 사본 개수λ₯Ό 1개둜 μ •ν•˜κ³  μ‹Άλ‹€λ©΄ static member둜 λ§Œλ“€μž

class GamePlayer{
    private:
        static const int numTurns = 5; //μ„ μ–Έ
        int scores[numTurns];
}

caution static member둜 λ§Œλ“€μ–΄μ§€λŠ” μ •μˆ˜λ₯˜ νƒ€μž…(각쒅 μ •μˆ˜νƒ€μž…, char, bool λ“±)의 클래슀 λ‚΄λΆ€ μƒμˆ˜λŠ” μ„ μ–Έλ§Œ 해도 λœλ‹€!
단, 클래슀 μƒμˆ˜μ˜ μ£Όμ†Œλ₯Ό κ΅¬ν•˜λŠ” 경우, μ»΄νŒŒμΌλŸ¬κ°€ μ •μ˜λ₯Ό 해라고 ν•˜λŠ” κ²½μš°μ—λŠ” λ³„λ„λ‘œ μ •μ˜ν•΄μ•Ό ν•œλ‹€.

const int GamePlayer::numTurns; //μ •μ˜

클래슀 μƒμˆ˜λŠ” μ„ μ–Έν•  λ•Œ μ΄ˆκΈ°ν™”ν•˜λ―€λ‘œ μ •μ˜ν•  λ•ŒλŠ” 값을 μ£Όμ§€ μ•ŠλŠ”λ‹€. 이 λ•Œ, 였래된 컴파일러 쀑 λ°˜λŒ€λ‘œ static 클래슀 멀버가 μ„ μ–Έν•  λ•Œ μ΄ˆκΈ°κ°’μ„ μ€˜μ„œλŠ” μ•ˆλœλ‹€κ³  ν•˜λŠ” κ²½μš°λ„ μžˆμœΌλ‹ˆ, 이 λ•ŒλŠ” λ°˜λŒ€λ‘œ ν•œλ‹€. 이에 λŒ€ν•œ ν•΄κ²°μ±…μœΌλ‘œ λ‚˜μ—΄μž λ‘”κ°‘μˆ (enum hack)이 μžˆλ‹€.

caution #defineλŠ” 클래슀 μƒμˆ˜λ₯Ό μ •μ˜ν•˜λŠ”λ° μ“Έ 수 μ—†κ³ , private λ“± μΊ‘μŠν™”λ„ μ•ˆλœλ‹€.


λ‚˜μ—΄μž λ‘”κ°‘μˆ (enum hack)
enum은 int λŒ€μ‹  μ‚¬μš©ν•  수 μžˆλ‹€.
class GamePlayer{
  private:
      enum{numTurns = 5};
      int scores[numTurns];
}
01. λ™μž‘ 방식이 #define에 가깝닀.
  • enum은 #define처럼 μ£Όμ†Œλ₯Ό 얻을 수 μ—†λŠ”λ°, μ‚¬μš©μžκ°€ μ •μˆ˜ μƒμˆ˜μ˜ μ£Όμ†Œλ₯Ό μ–»κ±°λ‚˜ 참쑰자λ₯Ό μ“°λŠ” 것을 막고 싢을 λ•Œ μœ μš©ν•˜λ‹€.
  • enum은 #define처럼 λ©”λͺ¨λ¦¬ 할당을 μ ˆλŒ€ ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • μ œλŒ€λ‘œλœ μ»΄νŒŒμΌλŸ¬λŠ” μ •μˆ˜ νƒ€μž…μ˜ const 객체에 λŒ€ν•΄ κ·Έ 객체에 λŒ€ν•œ ν¬μΈν„°λ‚˜ 참쑰자λ₯Ό λ§Œλ“€μ§€ μ•ŠλŠ” 이상, λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜μ§€ μ•ŠλŠ”λ‹€.
    • μ»΄νŒŒμΌλŸ¬λ§ˆλ‹€ λ‹€λ₯Ό 수 μžˆμœΌλ―€λ‘œ μ•ˆμ „ν•˜κ²Œ ν•˜κ³  μ‹Άλ‹€λ©΄ enum을 μ“°μž.
02. template metaprogramming의 핡심이닀.

ν•¨μˆ˜μ²˜λŸΌ μ“°λŠ” λ§€ν¬λ‘œκ°€ ν•„μš”ν•˜λ©΄, inline ν•¨μˆ˜(μž„μ˜μ˜ 클래슀 λ‚΄λΆ€μ—μ„œλ§Œ μ“Έ 수 있음)에 λŒ€ν•œ template을 μ‚¬μš©ν•˜μž.

issue 맀크둜 ν•¨μˆ˜λ₯Ό μ£Όμ˜ν•˜μž!
맀크둜 ν•¨μˆ˜λŠ” ν•¨μˆ˜μ²˜λŸΌ μƒκ²Όμ§€λ§Œ ν•¨μˆ˜ 호좜 overheadλ₯Ό μΌμœΌν‚€μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ‚¬μš©ν•œλ‹€.

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

int a = 5, b = 0;
MAX(++a, b); //a==7
MAX(++a, b+10); //a==6

fκ°€ 호좜되기 전에 aκ°€ μ¦κ°€ν•˜λŠ” νšŸμˆ˜κ°€ 달라진닀.

Solution ν•¨μˆ˜μ²˜λŸΌ μ“°λŠ” λ§€ν¬λ‘œκ°€ ν•„μš”ν•˜λ©΄, inline ν•¨μˆ˜(μž„μ˜μ˜ 클래슀 λ‚΄λΆ€μ—μ„œλ§Œ μ“Έ 수 있음)에 λŒ€ν•œ template을 μ‚¬μš©ν•˜μž.

template<typename T>
inline void max(const T& a, const T& b){
    f(a>b?a:b);
}

03. const

constλ₯Ό λΆ™μ—¬ μ„ μ–Έν•˜λ©΄ μ»΄νŒŒμΌλŸ¬κ°€ μ—λŸ¬λ₯Ό μž‘λŠ”λ° 도움이 λœλ‹€.

const
  • 의미적인 μ œμ•½: const ν‚€μ›Œλ“œκ°€ 뢙은 κ°μ²΄λŠ” μ™ΈλΆ€ 변경이 μ•ˆλœλ‹€.
  • 의미적인 μ œμ•½μ„ μ†ŒμŠ€ μ½”λ“œ μˆ˜μ€€μ—μ„œ 뢙이고, μ»΄νŒŒμΌλŸ¬κ°€ μ œμ•½μ„ μ§€μΌœμ€€λ‹€.
  • μ–΄λ–€ 값이 λΆˆλ³€μ΄μ–΄μ•Ό ν•œλ‹€λŠ” μ œμž‘μžμ˜ μ˜λ„λ₯Ό μ»΄νŒŒμΌλŸ¬μ™€ λ‹€λ₯Έ ν”„λ‘œκ·Έλž˜λ¨Έμ™€ λ‚˜λˆŒ 수 μžˆλŠ” μˆ˜λ‹¨μ΄λ‹€.

constλŠ” μ–΄λ–€ 유효 λ²”μœ„μ— μžˆλŠ” 객체에도 뢙을 수 있고, ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜, λ°˜ν™˜νƒ€μž…, λ©€λ²„ν•¨μˆ˜ 등에 뢙을 수 μžˆλ‹€.

  • 였λ₯ΈνŽΈμ„ κΎΈλ©°μ€€λ‹€κ³  μ—¬κΈ°μž.
01. 포인터
char str[] = "string";
char *p = a; //λΉ„μƒμˆ˜ 포인터, λΉ„μƒμˆ˜ 데이터
const char *p = a; //λΉ„μƒμˆ˜ 포인터, μƒμˆ˜ 데이터
char* const p = a; //μƒμˆ˜ 포인터, λΉ„μƒμˆ˜ 데이터
const char* const p = a; //μƒμˆ˜ 포인터, μƒμˆ˜ 데이터
void f1(const Widget *pw); //μƒμˆ˜ Widget 객체에 λŒ€ν•œ 포인터
void f2(Widget const *pw); //μƒμˆ˜ Widget 객체에 λŒ€ν•œ 포인터 == const Widget *
02. STL 반볡자(iterator)

STL λ°˜λ³΅μžλŠ” 포인터λ₯Ό 본뜬 κ²ƒμ΄μ–΄μ„œ 기본적으둜 T* 와 λΉ„μŠ·ν•˜κ²Œ λ™μž‘ν•œλ‹€. (T* const: μƒμˆ˜ 포인터, λΉ„μƒμˆ˜ 데이터)
λ°˜λ³΅μžλŠ” μžμ‹ μ΄ κ°€λ¦¬ν‚€λŠ” λŒ€μƒμ΄ μ•„λ‹Œ 것을 κ°€λ¦¬ν‚€λŠ” κ²½μš°κ°€ ν—ˆμš©λ˜μ§€ μ•ŠλŠ”λ‹€. (포인터 λ³€κ²½ X)
λŒ€μ‹  λ°˜λ³΅μžκ°€ κ°€λ¦¬ν‚€λŠ” λŒ€μƒ 자체λ₯Ό λ³€κ²½ν•  μˆ˜λŠ” μžˆλ‹€.

issue λ³€κ²½ λΆˆκ°€λŠ₯ν•œ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” λ°˜λ³΅μžκ°€ ν•„μš”ν•˜λ‹€λ©΄?
Solution const_iterator λ₯Ό μ‚¬μš©ν•œλ‹€. (const T*: λΉ„μƒμˆ˜ 포인터, μƒμˆ˜ 데이터)

std::vector<int> vec;
const std::vector<int>::iterator iter = vec.begin();
*iter = 10; 
++iter; //error

const std::vector<int>::const_iterator cIter = vec.begin();
*cIter = 10; //error
++cIter;
03. ν•¨μˆ˜ μ„ μ–Έ

ν•¨μˆ˜λ₯Ό const둜 μ„ μ–Έν•˜λ©΄ 쒋은 점은 μ‚¬μš©μž μ •μ˜ νƒ€μž…μ„ μ‚¬μš©ν•  λ•Œ μ‹€μˆ˜ν•˜μ§€ μ•Šμ„ 수 μžˆλ‹€λŠ” 점이닀.
μ‚¬μš©μž μ •μ˜ νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄, κΈ°λ³Έ νƒ€μž…κ³Ό 쓸데없이 λΉ„ν˜Έν™˜μ„±μ„ ν•˜μ§€ μ•Šλ„λ‘ ν•΄μ£ΌλŠ” νŠΉμ§•μ΄ μžˆλ‹€.

Widget a, b, c;
//쓸데없이 λΉ„ν˜Έν™˜μ„±μ„ ν•˜μ§€ μ•Šλ„λ‘ ν•΄μ£ΌλŠ” νŠΉμ§•λ•Œλ¬Έμ— ν—ˆμš©λ˜λŠ” 것이 λ¬Έμ œλ‹€.
if (a * b = c){ //λΉ„κ΅ν•˜λ €κ³  ν–ˆμ—ˆλŠ”λ°, λŒ€μž…ν•΄λ²„λ Έλ‹€.  
    ...
}
04. λ§€κ°œλ³€μˆ˜
05. μƒμˆ˜ 멀버 ν•¨μˆ˜: ν•΄λ‹Ή 멀버 ν•¨μˆ˜κ°€ μƒμˆ˜ 객체에 λŒ€ν•΄ 호좜될 ν•¨μˆ˜μ΄λ‹€. (ex: auto func() const -> void)
  • 클래슀의 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄ν•΄ν•˜κΈ° 쉽닀.
    • 클래슀둜 λ§Œλ“€μ–΄μ§„ 객체λ₯Ό λ³€κ²½ν•  수 μžˆλŠ” ν•¨μˆ˜μ™€ λ³€κ²½ν•  수 μ—†λŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©μžκ°€ 미리 μ•Œ 수 μžˆλ‹€.
  • μƒμˆ˜ 객체λ₯Ό μ‚¬μš©ν•  수 있게 ν•œλ‹€.
    • μƒμˆ˜ 객체에 λŒ€ν•œ 참쑰자둜 객체λ₯Ό μ „λ‹¬ν•˜λ©΄ μ„±λŠ₯에 μœ λ¦¬ν•˜λ‹€.
    • μƒμˆ˜ λ§€κ°œλ³€μˆ˜λ₯Ό μ‘°μž‘ν•  수 μžˆλŠ” const 멀버 ν•¨μˆ˜κ°€ ν•„μš”ν•˜λ‹€.

논리적인 μƒμˆ˜μ„±μ„ μ‚¬μš©ν•΄μ„œ ν”„λ‘œκ·Έλž˜λ°ν•œλ‹€.
μƒμˆ˜ 멀버와 λΉ„μƒμˆ˜ 멀버 ν•¨μˆ˜κ°€ κΈ°λŠ₯적으둜 μ„œλ‘œ λ˜‘κ°™μ΄ κ΅¬ν˜„λ˜μ–΄ μžˆλ‹€λ©΄, μ½”λ“œ 쀑볡을 ν”Όν•˜λŠ” 것이 μ’‹λ‹€. 이 λ•Œ, λΉ„μƒμˆ˜ 버전이 μƒμˆ˜ 버전을 ν˜ΈμΆœν•˜λ„λ‘ ν•˜μž.