E D R , A S I H C RSS

EffectiveC++

์ž‘์„ฑ์ž: ๊น€์˜ํ˜„(erunc0)

Effective C++ ์š”์•ฝ

Contents

1. Shifting from C to C++
1.1. Item1: Prefer const and inline to #define
1.2. Item 2: Prefer iostream to stdio.h
1.3. Item 3: Prefer new and delete to malloc and free
1.4. Item 4: Prefer C++-style comments
2. Memory management
2.1. Item 5: Use the same form in corresponding uses of new and delete
2.2. Item 6: Use delete on pointer members in destructors
2.3. Item 7: Be prepared for out-of-memory conditions.
2.4. Item 8: Adhere to convention when writing operator new and operator delete
2.5. Item 9: Avoid hiding the "normal" form of new
2.6. Item 10: Write operator delete if you write operator new
3. Constructors, Destructors, and Assignment Operators (ํด๋ž˜์Šค์— ๊ด€ํ•œ๊ฒƒ๋“ค.)
3.1. Item 11: Declare a copy constructor and an assignment operator for classes with dynamically allocated memory
3.2. Item 12: Prefer initialization to assignment in constructors
3.3. Item 13: List members in an initialization list in the order in which they are declared
3.4. Item 14: Make sure base classes have virtual destructors
3.5. Item 15: Have operator= return a reference to *this
3.6. Item 16: Assign to all data members in operator=
3.7. Item 17: Check for assignment to self in operator=
4. Classes and Functions: Design and Declaration
4.1. Item 18. ์ตœ์†Œํ•œ์˜ ์™„์ „ํ•œ ํด๋ž˜์Šค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ถ”๊ตฌํ•œ๋‹ค.
4.2. Item 19. ๋ฉค๋ฒ„ ํ•จ์ˆ˜, ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜ ๋ฐ ํ”„๋ Œ๋“œ ํ•จ์ˆ˜๋ฅผ ๊ตฌ๋ณ„ํ•œ๋‹ค.
4.3. Item 20. ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋ฅผ ๊ณต์šฉ(public) ์ธํ„ฐํŽ˜์ด์Šค์— ํฌํ•จ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.
4.4. Item 21. ๊ฐ€๋Šฅํ•œ const๋ฅผ ์ด์šฉํ•œ๋‹ค.
4.5. ํ•ญ๋ชฉ 22. ๊ฐ’์— ์˜ํ•œ ํ˜ธ์ถœ๋ณด๋‹ค๋Š” ๋ ˆํผ๋Ÿฐ์Šค์— ์˜ํ•œ ํ˜ธ์ถœ์„ ์„ ํ˜ธํ•œ๋‹ค.
4.6. ํ•ญ๋ชฉ 23. ๊ฐ์ฒด ๋ฐ˜ํ™˜์‹œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.
4.7. ํ•ญ๋ชฉ 24. ํ•จ์ˆ˜ ์˜ค๋ฒ„๋กœ๋”ฉ๊ณผ ๋””ํดํŠธ ์ธ์ž๊ฐ’ ์ค‘์—์„œ ์ฃผ์˜๊นŠ๊ฒŒ ์„ ํƒํ•œ๋‹ค.
4.8. ํ•ญ๋ชฉ 25. ํฌ์ธํ„ฐ๋‚˜ ์ˆ˜์น˜ํ˜• ํƒ€์ž…์ƒ์˜ ์˜ค๋ฒ„๋กœ๋”ฉ์„ ํ”ผํ•œ๋‹ค.
4.9. ํ•ญ๋ชฉ 26. ์ž ์žฌ์  ๋ชจํ˜ธ์„ฑ์„ ๊ฒฝ๊ณ„ํ•œ๋‹ค.
4.10. ํ•ญ๋ชฉ 27. ์˜๋„ํ•˜์ง€ ์•Š์€ ๋‚ด๋ถ€ ์ƒ์„ฑ ๋ฉค๋ฒ„ ํ•จ์ˆ˜์˜ ์ด์šฉ์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ง‰๋Š”๋‹ค.
4.11. ํ•ญ๋ชฉ 28. ์ „์—ญ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๋ถ„ํ• ํ•œ๋‹ค.
5. ํด๋ž˜์Šค์™€ ํ•จ์ˆ˜ : ๊ตฌํ˜„
5.1. ํ•ญ๋ชฉ 29. ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ "ํ•ธ๋“ค"์„ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•ด๋ผ.
5.2. ํ•ญ๋ชฉ 30. ์ ‘๊ทผํ•˜๊ธฐ ์–ด๋ ค์šด ๋ฉค๋ฒ„์— ๋Œ€ํ•œ ๋น„์ƒ์ˆ˜ ํฌ์ธํ„ฐ๋‚˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜ ์‚ฌ์šฉ์„ ํ”ผํ•˜๋ผ.
5.3. ํ•ญ๋ชฉ 31. ์ง€์—ญ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๋‚˜ ํ•จ์ˆ˜ ๋‚ด์—์„œ new๋ฅผ ์ด์šฉํ•ด ์ดˆ๊ธฐํ™”๋œ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฐธ์กฐ๋ฅผ ๋ฆฌํ„ดํ•˜์ง€ ๋ง๋ผ.
5.4. ํ•ญ๋ชฉ 32. ๋ณ€์ˆ˜ ์ •์˜๋Š” ๊ฐ€๋Šฅํ•œ ๋’ค๋กœ ๋Šฆ์ถฐ๋ผ.
5.5. ํ•ญ๋ชฉ 33. ์ธ๋ผ์ธ์„ ์„ ๋ณ„์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ผ.
5.6. ํ•ญ๋ชฉ 34. ํŒŒ์ผ๊ฐ„์˜ ์ปดํŒŒ์ผ ์˜์กด์„ฑ(dependency)์„ ์ตœ์†Œํ™”ํ•˜๋ผ.
6. ์ธ์Šคํ„ด์Šค์™€ ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„
6.1. ํ•ญ๋ชฉ 35. public ๊ณ„์Šน์ด "isa"๋ฅผ ๋ชจ๋ธ๋งํ•˜๋„๋ก ํ•˜๋ผ.
6.2. ํ•ญ๋ชฉ 36. ์ธํ„ฐํŽ˜์ด์Šค ๊ณ„์Šน๊ณผ ๊ตฌํ˜„ ๊ณ„์Šน์˜ ์ฐจ์ด์ ์„ ์ดํ•ดํ•˜๋ผ.
6.3. ํ•ญ๋ชฉ 37. ๊ณ„์Šน๋œ ๋น„๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
6.4. ํ•ญ๋ชฉ 38. ๊ณ„์Šน๋œ ๋ถ€์žฌ ์ธ์ž๊ฐ’์„ ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
6.5. ํ•ญ๋ชฉ 39. ๊ณ„์ธต๋„์˜ ์•„๋ž˜์ชฝ ํด๋ž˜์Šค๋ฅผ ๋‹ค์šด์บ์ŠคํŠธ(downcast)ํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
6.6. ํ•ญ๋ชฉ 40. ๋ ˆ์ด์–ด๋ง(layering)์„ ํ†ตํ•ด "๊ฐ€์ง€๊ณ  ์žˆ๋Š”" ๊ฒƒ๊ณผ "์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋œ" ๊ฒƒ์„ ๋ชจ๋ธ๋งํ•˜๋„๋ก ํ•˜์ž.
6.7. ํ•ญ๋ชฉ 41. ๊ณ„์Šน๊ณผ ํ…œํ”Œ๋ฆฟ๊ณผ์˜ ์ฐจ์ด์ ์„ ์ดํ•ดํ•œ๋‹ค.
6.8. ํ•ญ๋ชฉ 42. private ๊ณ„์Šน์„ ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋ผ.
6.9. ํ•ญ๋ชฉ 43. ๋‹ค์ค‘ ๊ณ„์Šน์„ ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋ผ.
6.10. ํ•ญ๋ชฉ 44. ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋ฅผ ํ‘œํ˜„ํ•˜๋„๋ก ํ•˜๋ผ. ์ž์‹ ์ด ํ‘œํ˜„ํ•œ ๊ฒƒ์˜ ์˜๋ฏธ๋ฅผ ์ดํ•ดํ•˜๋„๋ก ํ•˜๋ผ.
7. ๋ฏธ๋ฌ˜ํ•œ ๋ถ€๋ถ„
7.1. ํ•ญ๋ชฉ 45. C++๊ฐ€ ์€๋ฐ€ํ•˜๊ฒŒ ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ํ˜ธ์ถœํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ
7.2. ํ•ญ๋ชฉ 46. ์‹คํ–‰ ์‹œ๊ฐ„ ์—๋Ÿฌ๋ณด๋‹ค๋Š” ์ปดํŒŒ์ผ ์‹œ๊ฐ„๊ณผ ๋งํฌ ์‹œ๊ฐ„ ์—๋Ÿฌ๊ฐ€ ์ข‹๋‹ค.
7.3. ํ•ญ๋ชฉ 47. ๋น„์ง€์—ญ ์ •์ (Non-local static) ๊ฐ์ฒด๋Š” ์‚ฌ์šฉ๋˜๊ธฐ ์ „์— ์ดˆ๊ธฐํ™”๋˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.
7.4. ํ•ญ๋ชฉ 48. ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๊ฒฝ๊ณ (Warning)์— ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์—ฌ๋ผ.
7.5. ํ•ญ๋ชฉ 49. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž˜ ์•Œ์•„๋‘์ž.
7.6. ํ•ญ๋ชฉ 50. C++์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋„“ํ˜€๋ผ.
8. Thread

1. Shifting from C to C++

1.1. Item1: Prefer const and inline to #define

preprocessor(์ „์ฒ˜๋ฆฌ๊ธฐ)๋ณด๋‹ค๋Š” compiler๋ฅผ ์„ ํ˜ธํ•œ๋‹ค๋Š” ๋œป.

DeleteMe #define(preprocessor)๋ฌธ์— ๋Œ€ํ•ด const์™€ inline์„(compile)์˜ ์ด์šฉ์„ ์ถ”์ฒœํ•œ๋‹ค. --์ƒ๋ฏผ

-> const

~cpp 
   #define ASPECT_RATIO 1.653
ASPECT_RATIO๋Š” ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ์ปดํŒŒ์ผ๋กœ ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— ์ „์ฒ˜๋ฆฌ๊ธฐ์— ์˜ํ•ด ์ œ๊ฑฐ๋œ๋‹ค.

instead of upper..


define ๋œ ASPECT_RATIO ๋ž€ ์ƒ์ˆ˜๋Š” 1.653์œผ๋กœ ๋ณ€๊ฒฝ๋˜๊ธฐ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ASPECT_RATIO ๋ž€๊ฒƒ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ชจ๋ฅด๊ณ  symbol table ์—?๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค. ์ด๋Š” debugging์„ ํ• ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. -์ธํƒ
~cpp 
   const double ASPECT_RATIO = 1.653
์ฑ…์—์„œ ์–ธ๊ธ‰ํ•œ ๋‘๊ฐ€์ง€.

~cpp 
1. ์ƒ์ˆ˜ ํฌ์ธํ„ฐ(constant pointer)๋ฅผ ์ •์˜ํ•˜๊ธฐ๊ฐ€ ๋‹ค์†Œ ๊นŒ๋‹ค๋กœ์›Œ ์ง„๋‹ค๋Š” ๊ฒƒ.
   - ex -   
   const char * const authorName = "Scott Meyers";

2. ์ƒ์ˆ˜์˜ ์˜์—ญ์„ ํด๋ž˜์Šค๋กœ ์ œํ•œํ•˜๊ธฐ ์œ„ํ•ด์„  ์ƒ์ˆ˜๋ฅผ ๋ฉค๋ฒ„๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฉฐ
   ๊ทธ ์ƒ์ˆ˜์— ๋Œ€ํ•œ ๋‹จ ํ•œ๊ฐœ์˜ ๋ณต์‚ฌ๋ณธ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์‹ ํ•˜๊ธฐ ์œ„ํ•ด์„œ static์œผ๋กœ
   ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
   - ex -
   // header.
   class GamePlayer 
   {
   private:
         static const int NUM_TURNS = 5;   // ์ƒ์ˆ˜ ์„ ์–ธ! (์„ ์–ธ๋งŒ ํ•œ๊ฒƒ์ž„)
         int scores[NUM_TURNS];            // ์ƒ์ˆ˜์˜ ์‚ฌ์šฉ.
   }

   // source file
   ...
   const int GamePlayer::NUM_TURNS;        // ์ •์˜๋ฅผ ๊ผญํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
   ...


#define -> inline (๋งคํฌ๋กœ ์‚ฌ์šฉ์‹œ)
  • inline: ํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ ์ธํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ผ์ˆ˜ ์žˆ๋Š”.. ๊ฑฐ์‹œ๊ธฐ. ๊ถ๊ธˆํ•˜๋ฉด ์ฑ…์ฐพ์•„๋ณด์„ธ์š”.

~cpp 
   - ex -
   #define max(a,b) ((a) > (b) ? (a) : (b))
       // ๋งคํฌ๋กœ ์ž‘์„ฑ์‹œ์—๋Š” ์–ธ์ œ๋‚˜ ๋งคํฌ๋กœ ๋ชธ์ฒด์˜ ๋ชจ๋“  ์ธ์ž๋“ค์„ ๊ด„ํ˜ธ๋กœ ๋ฌถ์–ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
       // ์™œ์ธ์ง€๋Š” ๋‹ค๋“ค ์•Œ๊ฒƒ์ด๋‹ค. 
   
   // #define ์„ inline์œผ๋กœ..
   inline int max(int a, int b) { return a > b ? a : b; } // intํ˜•์œผ๋กœ๋งŒ ์ œํ•œ ๋˜์–ด์žˆ๋„ค.. 

   // template์œผ๋กœ
   template class<T>
   inline const T& max (const T& a, const T& b) { return a > b ? a : b; }
const์™€ inline์„ ์“ฐ์ž๋Š” ์–˜๊ธฐ์˜€์Šต๋‹ˆ๋‹ค. --; ์™œ ๊ทธ๋Ÿฐ์ง€๋Š” ์•„์‹œ๋Š” ๋ถ„๊ป˜์„œ ๊ธ€์ข€ ๋‚จ๊ธฐ์‹œ๊ตฌ์š”. ^^

#define ๋ฌธ์„ const์™€ inline์œผ๋กœ ๋Œ€์ฒดํ•ด์„œ ์จ๋„, #ifdef/#ifndef - #endif ๋“ฑ.. ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ๋“ค์€

์•„์ง๊นŒ์ง€ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ์•ˆ์“ธํ•„์š”๋Š” ์—†๊ฒ ์ฃ ?

๋งคํฌ๋กœ๋Š” ๋ง ๊ทธ๋Œ€๋กœ ์น˜ํ™˜์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๊ทธ ๋ฐœ์ƒํ•  ํ™•๋ฅ ์ด ๋†’์Œ. ์ƒ์ˆ˜์„ ์–ธ์ด๋‚˜ ํ•จ์ˆ˜์„ ์–ธ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ๊ฐ€๊ธ‰์  const ๋‚˜ inline์œผ๋กœ ๋Œ€์ฒดํ•˜๋Š”๊ฒŒ ์ข‹๊ฒ ์ง€. (์œผ.. ๊ทธ๋ž˜๋„ ์‹ค์ œ๋กœ ์งค๋•Œ๋Š” ์ƒ์ˆ˜ ์„ ์–ธํ• ๋•Œ๋Š” #define ๋‚จ์šฉ ๊ฒฝํ–ฅ์ด..

๊ทธ๋Ÿผ.. ํ•ญ๋ชฉ1 end.

ํšก์„ค์ˆ˜์„ค.

1.2. Item 2: Prefer iostream to stdio.h

scaf/printf -> cin/cout

1.3. Item 3: Prefer new and delete to malloc and free

* malloc & free
  • ์ƒ์„ฑ์ž(constructor)์™€ ์†Œ๋ฉธ์ž(destructor)์˜ ์กด์žฌ๋ฅผ ๋ชจ๋ฅธ๋‹ค.
* new & delete
  • ์ƒ์„ฑ์ž ๋ฐ ์†Œ๋ฉธ์ž์™€ ์ ์ ˆํžˆ ์ƒํ˜ธ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—. they are clearly the superior choice.

1.4. Item 4: Prefer C++-style comments

/* */: C style์˜ ์ฃผ์„

// : C++ style์˜ ์ฃผ์„

์ž๊ธฐ๋งŒ์˜ ์ฃผ์„์„ ์“ฐ๋ฉด ๋˜๋Š”๊ฑฐ ์•„๋‹ˆ์•ผ? ๋‚œ. ์ฃผ์„๋‹ค๋Š”๊ฒŒ ์ œ์ผ ์‹ซ์€๋ฐ. ^^;

๋ช‡๋‹ฌ ์ง€๋‚œ ํ”„๋กœ๊ทธ๋žจ์€ ์ž๊ธฐ๊ฐ€ ๋งŒ๋“ ๊ฒŒ ์•„๋‹Œ๊ฑฐ์•ผ!? , ์˜ˆ์ „์— ์ƒ๋ฏผ์ด ํ˜•์ด ์–˜๊ธฐํ•ด์ค€.. --;; ใ…Žใ…Žใ…Ž ๋™๊ฐ..

2. Memory management

๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์˜ฌ๋ฐ”๋กœ ์–ป๋Š” ๊ฒƒ๊ณผ ๊ทธ๊ฒƒ์„ ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š”๊ฒƒ(?)์— ๊ด€ํ•œ ์–˜๊ธฐ๋“ค.

2.1. Item 5: Use the same form in corresponding uses of new and delete

~cpp 
string *stringArray = new string[100];
...
delete stringArray;   // delete๋ฅผ ์ž˜๋ชป ์จ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.
// stringArray์— ์˜ํ•ด ๊ฐ€๋ฅด์ผœ์ง„ 100๊ฐœ์˜ string object๋“ค์ค‘์— 99๊ฐœ๋Š” ์ œ๋Œ€๋กœ ์ œ๊ฑฐ๊ฐ€ ์•ˆ๋จ.
  • new๋ฅผ ํ˜ธ์ถœํ• ๋•Œ []๋ฅผ ์ด์šฉํ–ˆ๋‹ค๋ฉด delete์˜ ํ˜ธ์ถœ์‹œ์—๋„ []๋ฅผ์ด ์šฉํ•œ๋‹ค. ๊ฐ„๋‹จ๊ฐ„๋‹จ!
typedef๋ฅผ ์‚ฌ์šฉํ–ˆ์„๋•Œ์˜ delete.. --? : ์ƒˆ๋กœ์šด ๋ฌธ์ œ ์ œ๊ธฐ
~cpp 
typedef string AddressLines[4];      // ๊ฐœ์ธ ์ฃผ์†Œ๋Š” 4๊ฐœ์˜ ์ค„์„ ์ฐจ์ง€ํ•˜๊ณ 
                                     // ๊ฐ๊ฐ์ด ์ŠคํŠธ๋ง์ด๋‹ค.
...
string *pal = new AddressLines;      // "new AddressLines" returns a string *, just "new string[4]".. 
...
delete pal;     // ์–ด๋–ป๊ฒŒ ๋ ์ง€ ๋ชฐ๋ผ~
delete [] pal;  // fine.
์ด๋Ÿฐ ํ˜ผ๋ž€(?)์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„  ๋ฐฐ์—ด ํƒ€์ž…๋“ค์— ๋Œ€ํ•œ typedef๋ฅผ ํ”ผํ•˜๋ฉด ๋˜์ง€๋ญ. ^^

2.2. Item 6: Use delete on pointer members in destructors

๋™์  ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ํ–‰ํ•˜๋Š” ํด๋ž˜์Šค๋“ค์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ƒ์„ฑ์ž์— new๋ฅผ ์“ด๋‹ค. (CString class๊ฐ™์€๊ฒƒ๋“ค?)

๋‚˜์ค‘์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜๊ธฐ ์œ„ํ•ด์„œ ์†Œ๋ฉธ์ž์—์„œ delete๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜, ๋‚˜์ค‘์— ์ด๋ ‡๊ฒŒ ๋งŒ๋“  ํด๋ž˜์Šค๋ฅผ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๊ฐœ์„ ๋ ๊ฒฝ์šฐ ๊ทธ๋ฆฌ๊ณ , ๊ฐœ์„ ๋œ ํด๋ž˜์Šค์—์„œ ํฌ์ธํ„ฐ ๋ฉค๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒŒ

๋œ๋‹ค๋ฉด ๋ฐ‘์˜ ์„ธ๊ฐ€์ง€๋ฅผ ์ˆ™์ง€ํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค.
  • Initialization of the pointer in each of the constructors. If no memory is to be allocated to the pointer in a particular constructor, the pointer should be initialized to 0 (i.e., the null pointer). - ์ƒ์„ฑ์ž ๊ฐ๊ฐ์—์„œ ํฌ์ธํ„ฐ ์ดˆ๊ธฐํ™”
  • Deletion of the existing memory and assignment of new memory in the assignment operator. - ํฌ์ธํ„ฐ ๋ฉค๋ฒ„์— ๋‹ค์‹œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•  ๊ฒฝ์šฐ ๊ธฐ์กด์˜ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ์™€ ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ์˜ ํ• ๋‹น
  • Deletion of the pointer in the destructor. - ์†Œ๋ฉธ์ž์—์„œ ํฌ์ธํ„ฐ ์‚ญ์ œ
์œ„์˜ ์„ธ๊ฐ€์ง€์ค‘ ์ฒ˜์Œ์˜ 2๊ฐ€์ง€๋Š” ์ œ๋Œ€๋กœ ์•ˆํ•ด์ฃผ๋ฉด ๋ฐ”๋กœ๋ฐ”๋กœ ๋ˆˆ์— ๋„์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ดœ์ฐฎ์ง€๋งŒ,

์„ธ๋ฒˆ์งธ ์†Œ๋ฉธ์ž์—์„œ ํฌ์ธํ„ฐ ์‚ญ์ œ์— ๊ด€ํ•œ ๊ฒƒ์„ ์ œ๋Œ€๋กœ ์•ˆํ•ด์ฃผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์œ ์ถœ(memory leak)์œผ๋กœ ๊ทธ๋ƒฅ ์ฒ˜๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค์— ํฌ์ธํ„ฐ ๋ฉค๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ๋ฐ˜๋“œ์‹œ ๋ช…์‹ฌํ•ด์•ผ ํ•œ๋‹ค.

2.3. Item 7: Be prepared for out-of-memory conditions.

๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ• ๊ฒฝ์šฐ ์ ์ ˆํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค€๋‹ค๋Š” ์–˜๊ธฐ์ธ๊ฒƒ ๊ฐ™์€๋ฐ...

์ž˜๋ชจ๋ฅด๊ฒ ์Œ. ์•„์‹œ๋Š” ๋ถ„์˜ ์„ค๋ช…์ด ๋งค์šฐ ํ•„์š”ํ•จ

Comment ๋ถ€ํƒํ•ด์š”

๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์‹œ์— ๋Œ€ํ•œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ๋Œ€๋น„ํ•ด๋‘์–ด๋ผ ์ •๋„๋ฉด ์ ๋‹นํ•  ๊ฒƒ ๊ฐ™์€๋ฐ.


set_new_handler๋ฅผ ์ด์šฉํ•œ memory ํ• ๋‹น ์‹คํŒจ์ฒ˜๋ฆฌ.

~cpp 
typedef void (* new_handler) {}; // ํ•จ์ˆ˜ pointer
new_handler set_new_handler (new_handler p) throw ();
...
// ์—ฐ์‚ฐ์ž new๊ฐ€ ์ถฉ๋ถ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜์ง€ ๋ชปํ•  ๊ฒฝ์šฐ ํ˜ธ์ถœ๋  ํ•จ์ˆ˜
void noMoreMemory ()
{
    cerr << "Unable to satisfy request for memory\n";
    abort ();
}
...
void main ()
{
    set_new_handler (noMoreMemory);
    int *pVigdataArray = new int [100000000]; // 100000000๊ฐœ์˜ ์ •์ˆ˜๊ณต๊ฐ„์„ ํ• ๋‹นํ•  ์ˆ˜ ์—†๋‹ค๋ฉด noMoreMemory๊ฐ€ ํ˜ธ์ถœ.
    ...
}


๊ทธ๋ฆฌ๊ณ , class๋‚ด ์—์„œ operator new์™€ set_new_handler๋ฅผ ์ •ํ•ด ์คŒ์œผ๋กœ์จ ํ•ด๋‹น class๋งŒ์˜ ๋…ํŠน(?)ํ•œ

๋™์ž‘์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
~cpp 
class X {
public:
  static new_handler set_new_handler(new_handler p);
  static void * operator new(size_t size);
private:
  static new_handler currentHandler;
};
...
// source file (??.cpp)

new_handler X::currentHandler;      // sets currentHandler
                                    // to 0 (i.e., null) by
                                    // default
new_handler X::set_new_handler(new_handler p)
{
  new_handler oldHandler = currentHandler;
  currentHandler = p;
  return oldHandler;
}

void * X::operator new(size_t size)
{
  new_handler globalHandler =                // install X's
    std::set_new_handler(currentHandler);    // handler
  void *memory;
  try {                                      // attempt
    memory = ::operator new(size);           // allocation
  }
  catch (std::bad_alloc&) {                  // restore
    std::set_new_handler(globalHandler);     // handler;
    throw;                                   // propagate
  }                                          // exception

  std::set_new_handler(globalHandler);       // restore
                                             // handler
  return memory;
}
...
void noMoreMemory();                           // decl. of function to
                                               // call if memory allocation
                                               // for X objects fails
...
X::set_new_handler(noMoreMemory);
                                               // set noMoreMemory as X's
                                               // new-handling function

X *px1 = new X;                                // if memory allocation
                                               // fails, call noMoreMemory

string *ps = new string;                       // if memory allocation
                                               // fails, call the global
                                               // new-handling function
                                               // (if there is one)

X::set_new_handler(0);                         // set the X-specific
                                               // new-handling function
                                               // to nothing (i.e., null)

X *px2 = new X;                                // if memory allocation
                                               // fails, throw an exception
                                               // immediately. (There is
                                               // no new-handling function
                                               // for class X.)

๋‚ด ์ƒ๊ฐ์—๋Š” ์ด๋Ÿฐ๊ฒŒ ์žˆ๋‹ค๋ผ๊ณ ๋งŒ ์•Œ์•„๋‘๋ฉด ์ข‹์„๊ฒƒ ๊ฐ™๋‹ค. --;

2.4. Item 8: Adhere to convention when writing operator new and operator delete

operator new ์™€ operator delete ์˜ ์ž‘์„ฑ์‹œ ๋”ฐ๋ผ์•ผ ํ• ๊ฒƒ๋“ค.

''- ํ• ๋‹น ๋ฃจํ‹ด๋“ค์ด new ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜(memory ํ• ๋‹น์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ™์€ ๊ฑฐ๋“ค) ๋ฅผ ์ง€์›ํ•˜๊ณ 

ํฌ๊ธฐ๊ฐ€ 0์ธ ์š”๊ตฌ๋“ค์„ ์˜ฌ๋ฐ”๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

- ํ• ๋‹นํ•ด์ œ ๋ฃจํ‹ด๋“ค์ด ๋„ ํฌ์ธํ„ฐ์— ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
''



๋ฉค๋ฒ„๊ฐ€ ์•„๋‹Œ operator new
~cpp 
// operator new
void * operator new (size_t size)
{
if (size == 0) {                      // handle 0-byte requests
    size = 1;                           // by treating them as
  }                                     // 1-byte requests

  while (1) {

    // size bytes๋ฅผ ํ• ๋‹น..

    if (the allocation was successful)
      return (a pointer to the memory);
    
    new_handler globalHandler = set_new_handler(0);
    set_new_handler(globalHandler);

    if (globalHandler) (*globalHandler)();
    else throw std::bad_alloc();
  }

}
operator new ๊ฐ€ ํ•˜๋ถ€ ํด๋ž˜์Šค๋กœ ์ƒ์†๋œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

์œ„์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ถ€๋ถ„์„ ๋ณด๋ฉด size bytes๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น ํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, ์ด ํด๋ž˜์Šค๋ฅผ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ operator new ์—ฐ์‚ฐ์ž๊ฐ€ ์ƒ์†๋  ๊ฒฝ์šฐ.

์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค๋‚ด์— operator new์—ฐ์‚ฐ์ž๋ฅผ ๋‹ค์‹œ ์žฌ์ •์˜ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿผ ๋ฐ‘์˜ source๋ฅผ...
~cpp 
// in class
class Base {
public:
  static void * operator new(size_t size);
  ...
};

class Derived: public Base       // Derived doesn't declare
{ ... };                         // operator new

...
Derived *p = new Derived;        // calls Base::operator new!

// ๋งŒ์ผ Base์˜ operator new๊ฐ€ ์ด์— ๋Œ€์ฒ˜ํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๊ทธ๋ฅผ 
// ์œ„ํ•œ ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด "์ž˜๋ชป๋œ" ์–‘์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์š”์ฒญํ•˜๊ณ  ์žˆ๋Š”
// ํ˜ธ์ถœ๋“ค์„ ํ‘œ์ค€ operator new๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค
void *Base::operator new (size_t size)
{
  if (size != sizeof (Base))      // size๊ฐ€ ์ž˜๋ชป ๋˜์—ˆ์œผ๋ฉด
    return ::operator new (size); // ์š”๊ตฌ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค

  ... // ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์—ฌ๊ธฐ์„œ ์š”๊ตฌ๋ฅผ ์ฒ˜๋ฆฌํ•จ
}
๋ฉค๋ฒ„๊ฐ€ ์•„๋‹Œ operator delete
~cpp 
// operator delete
void operator delete(void *rawMemory)
{
  if (rawMemory == 0) return;    // do nothing if the null
                                 // pointer is being deleted

  // deallocate the memory pointed to by rawMemory;

  return;
}
์ด ์—ฐ์‚ฐ์ž๋„ ์—ญ์‹œ ์ƒ์†๋  ๊ฒฝ์šฐ ์•ฝ๊ฐ„ ๊ณจ์น˜์•„ํ”ˆ๊ฐ€?

์ด๊ฒƒ ์—ญ์‹œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•  ๊ฒƒ์˜ size๋ฅผ ๋„ฃ์–ด์„œ ํ•ด์ œํ•˜๊ธฐ ๋•Œ๋ฌธ์—.

operator new์—ฐ์‚ฐ์ž์ฒ˜๋Ÿผ ์ž˜(?) ์ฒ˜๋ฆฌ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
~cpp 
// in class
class Base {                       // same as before, but now
public:                            // op. delete is declared
  static void * operator new(size_t size);
  static void operator delete(void *rawMemory, size_t size);
  ...
};

void Base::operator delete(void *rawMemory, size_t size)
{
  if (rawMemory == 0) return;      // check for null pointer

  if (size != sizeof(Base)) {      // if size is "wrong,"
    ::operator delete(rawMemory);  // have standard operator
    return;                        // delete handle the request
  }

  // deallocate the memory pointed to by rawMemory;

  return;
}

2.5. Item 9: Avoid hiding the "normal" form of new

๊ฐ„๋‹จ. class ๋‚ด์— operator new๋ฅผ ๋งŒ๋“ค์–ด ์ค„๋•Œ.

~cpp 
class X {
public:
  void f();

  // new ํ•ธ๋“ค๋ง ํ•จ์ˆ˜์˜ ์‚ฌ์–‘์„ ๋งŒ์กฑํ•˜๋Š” ์—ฐ์‚ฐ์ž new
  static void * operator new(size_t size, new_handler p);
};

void specialErrorHandler();     // definition is elsewhere

X *px1 =  new (specialErrorHandler) X; // calls X::operator new

X *px2 = new X;   // error!, "์ •์ƒ form์— ๋Œ€ํ•ด ํ˜ธํ™˜์ด ์ด๋ฃจ์–ด ์ง€์ง€์•Š๋Š” ๋ฌธ์ œ์ ."

์œ„์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด.
~cpp 
class X 
{
public:
  void f();
  static void * operator new(size_t size, new_handler p);
  static void * operator new(size_t size) // normal formํ˜•์‹์˜ ์—ฐ์‚ฐ์ž๋„ ๋งŒ๋“ค์–ด์ค€๋‹ค.
  { return ::operator new(size); }
};
X *px1 =
  new (specialErrorHandler) X;      // calls X::operator
                                    // new(size_t, new_handler)
X* px2 = new X;                     // calls X::operator
                                    // new(size_t)
or
~cpp 
class X 
{
public:
  void f();
  static
    void * operator new(size_t size,                
                        new_handler p = 0);         // default ๊ฐ’์„ ์ฃผ์–ด์„œ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค
};
X *px1 = new (specialErrorHandler) X;               // ok
X* px2 = new X;                                     // ok
์–ด๋–ค ๋ฐฉ๋ฒ•์ด๋“  ์ƒ๊ด€ ์—†์ง€๋งŒ, code๋ฅผ ์•ฝ๊ฐ„์ด๋ผ๋„ ๋œ์น˜๋Š” defaut ์ธ์ž๋ฅผ ์ฃผ๋Š”๊ฒƒ์ด.. ใ…กใ…ก;; ํ•˜ํ•˜

2.6. Item 10: Write operator delete if you write operator new

operator new ์™€ operator delete๋Š” ์™œ ์“ธ๊นŒ?

ํšจ์œจ์„ฑ ๋•Œ๋ฌธ์ด๋ž๋‹ˆ๋‹ค. ์ƒˆ๋กœ ์ž‘์„ฑํ•ด์ฃผ๋Š”๊ฒŒ ์–ผ๋งˆ๋‚˜ ํฐ ํšจ์œจ์„ ๋ณด์ด๊ธฐ์— default๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ฒƒ์„

์“ฐ์ง€ ์•Š๋Š” ๊ฒƒ์ผ๊นŒ? --a ์‚ฌ์‹ค ๋ชฐ๋ž๋Š”๋ฐ, ์ผ๋ฐ˜ ์ ์€ new (default new์—ฐ์‚ฐ์ž)๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํ• ๋‹น๋œ ๋ธ”๋ก์˜

ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋‚ด ์ฃผ๋Š” ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ๊ฐ™์ด ๋ถ™์—ฌ memory๋ฅผ ํ• ๋‹นํ•ด ์ค€๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, operator new์—ฐ์‚ฐ์ž๋ฅผ

์ง์ ‘๋งŒ๋“ค์–ด ์ฃผ๊ฒŒ๋˜๋ฉด ์ด๋Ÿฐ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์•Š๋ถ™์—ฌ์ค˜๋„ ๋œ๋‹ค๋Š” ๊ตฐ์š”. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์ถ”๊ฐ€ ์ •๋ณด ํฌ๊ธฐ๋งŒํผ์˜ ์†์‹ค์„ ์ค„์ผ ์ˆ˜

์žˆ๋‹ค๋Š” ๋ง์ด์ง€์š”~ ํ•œ๋‹ค๋งˆ๋””๋กœ ํšจ์œจ์„ฑ์ด ์ข‹์•„์กŒ๋‹ค.(๋ฐ˜๋ฉด ::operator new๋Š” ์œ ์—ฐ์„ฑ์ด ์ข‹๋‹ค)

...


DeleteMe ๊ทธ๋Ÿฐ ์˜๋ฏธ๋ณด๋‹ค String ์ด๋‚˜, linked list ํ˜น์€ ๊ธฐํƒ€ ์—ฌ๋Ÿฌ ๊ธฐํƒ€ ๋ฐ์ดํ„ฐ ํ˜•์œผ๋กœ ๋งŽ์€ ์ˆ˜์˜ ํ• ๋‹น์„ ํ†ตํ•ด์„œ ์“ธ์ˆ˜ ์žˆ๋Š” ์ธ์ž์˜ ๊ฒฝ์šฐ์—๋Š” ์‚ฌ์šฉ์ž ์ •์˜ new๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ€๋Šฅํ•˜๋ฉด ๊ณต์šฉ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์—์„œ ํ™œ๋™์‹œ์ผœ์„œ, ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์ฝ”๋“œ๋ฅผ ์ค„์ด๊ณ  (๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์˜ new์™€ alloc๋Š” ์„ฑ๋Šฅ์— ๋งŽ์€ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.) ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ค„์ด๊ณ  ํšจ์œจ์  ๊ด€๋ฆฌ๋ฅผ ํ• ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋ฐ์ดํ„ฐ ํ˜•์œผ๋กœ ์“ฐ์ด๋Š” ์ธ์ž๊ฐ€ ์•„๋‹Œ ํ•œ app์•ˆ์—์„œ ๋‹จ ํ•œ๋ฒˆ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ํด๋ž˜์Šค๋ผ๋ฉด ๊ตฌ์ง€ new๋ฅผ ์„ฑ์˜ํ•ด์„œ memory leak์˜ ์œ„ํ—˜์„ฑ์„ ์ฆ๊ฐ€ ์‹œํ‚ค๋Š” ๊ฒƒ๋ณด๋‹ค, ์ผ๋ฐ˜์ ์ธ new์™€ ์ƒ์„ฑ์ž ํŒŒ๊ดด์ž์˜ ๊ทœ์น™์„ ์“ฐ๋Š”๊ฒƒ์ด ์ข‹์„๊ฒ๋‹ˆ๋‹ค. --์ƒ๋ฏผ

3. Constructors, Destructors, and Assignment Operators (ํด๋ž˜์Šค์— ๊ด€ํ•œ๊ฒƒ๋“ค.)

๊ฐ„๊ณผ ํ•˜๊ธฐ ์‰ฌ์šด ์ƒ์„ฑ์ž, ์†Œ๋ฉธ์ž, ์น˜ํ™˜ ์—ฐ์‚ฐ์ž์— ๋Œ€ํ•œ ์–˜๊ธฐ๋“ค.

3.1. Item 11: Declare a copy constructor and an assignment operator for classes with dynamically allocated memory

~cpp 
// ์™„๋ฒฝํ•˜์ง€ ์•Š์€ String class
class String {
public:
  String(const char *value);
  ~String();
private:
  char *data;
};

String::String(const char *value)
{
  if (value) {
    data = new char[strlen(value) + 1];
    strcpy(data, value);
  }
  else {
    data = new char[1];
    *data = '\0';
  }
}

inline String::~String() { delete [] data; }
์ด class์—๋Š” ์น˜ํ™˜ ์—ฐ์‚ฐ์ž๋‚˜ ๋ณต์‚ฌ ์ƒ์„ฑ์ž๊ฐ€ ์—†๋‹ค. ์ด๋Ÿฐ ํด๋ž˜์Šค๋Š” ์ข‹์ง€ ๋ชปํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.



๊ฐ์ฒด a์˜ ํฌ์ธํ„ฐ๋Š” ๋ฌธ์ž์—ด "Hello"๋ฅผ, ๊ฐ์ฒด b๋‚ด์˜ ํฌ์ธํ„ฐ๋Š” "World"๋ฌธ์ž์—ด์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์น˜ํ™˜์—ฐ์‚ฐ์„ ํ•˜๋ฉด..
~cpp 
b = a;
ํด๋ž˜์Šค ๋‚ด์— operator=๊ฐ€ ์ •์˜ ๋˜์–ด ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, C++์—์„œ default ์น˜ํ™˜ ์—ฐ์‚ฐ์ž๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

default ์น˜ํ™˜ ์—ฐ์‚ฐ์ž๋Š” ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์„ ํ•˜๋‚˜์”ฉ ์น˜ํ™˜ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— a์™€ b์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ data๋ฅผ

์ง์ ‘ ๋ณต์‚ฌ ํ•œ๋‹ค.



์ด ์ƒํƒœ๋Š” ์ ์–ด๋„ ๋‘๊ฐ€์ง€์˜ ๋ฌธ์ œ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

  • b์—์„œ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์‚ญ์ œ ๋˜์ง€ ์•Š์•˜์ง€ ๋•Œ๋ฌธ์—, ์˜์›ํžˆ ์ผ์–ด๋ฒ„๋ฆฌ๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ์ ์ธ memory leak.
  • a์™€ b๋ชจ๋‘ ๊ฐ™์€ ๋ฌธ์ž์—ด์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ๊ฐ–๊ฒŒ ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋‘˜์ค‘ํ•˜๋‚˜๊ฐ€ ์ง€์›Œ์ง€๊ฒŒ ๋˜๋ฉด ๋‚˜๋จธ์ง€ ํ•˜๋‚˜์—ญ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์žƒ์–ด ๋ฒ„๋ฆฌ๊ฒŒ ๋œ๋‹ค.
๋‘๋ฒˆ์งธ ์ƒํ™ฉ์˜ ์˜ˆ.
~cpp 
String a("Hello");      // a๋ฅผ ์ƒ์„ฑ
...
{                       // ์ƒˆ๋กœ์šด ์˜์—ญ
  String b("World");    // b๋ฅผ ์ƒ์„ฑ
  ...

  b = a;          // default ์น˜ํ™˜ ์—ฐ์‚ฐ์ž ์ˆ˜ํ–‰
                     // b์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์žƒ๊ฒŒ ๋œ๋‹ค.

}                 // ์˜์—ญ์ด ๋‹ซํžŒํ›„,
                  // b์˜ ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ, a๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋˜ data๋„ ์†Œ๋ฉธ๋˜๊ฒŒ ๋œ๋‹ค.

String c = a;     // c์˜ data๋Š” ์ •์˜ ๋˜์ง€ ์•Š๋Š”๋‹ค. 
                  // ๋ณต์‚ฌ ์ƒ์„ฑ์ž๊ฐ€ ์ •์˜ ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— C++์—์„œ ์ œ๊ณตํ•˜๋Š” default ์น˜ํ™˜ ์—ฐ์‚ฐ์ž ํ˜ธ์ถœ.
                  // a์˜ data๋Š” ์ด๋ฏธ ์ง€์›Œ ์กŒ๊ธฐ ๋•Œ๋ฌธ์— memory leak์˜ ๋ฌธ์ œ๋Š” ์—†๋‹ค.
                  // ๊ทธ๋Ÿฌ๋‚˜, c์™€ a๋Š” ๊ฐ™์€ ๊ณณ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ๊ทธ๋ฆฌ๊ณ , c์˜ ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ ๋˜๋ฉด ์œ„์—์„œ ์‚ญ์ œ๋œ ๊ณณ์„ ๋‹ค์‹œํ•œ๋ฒˆ 
                     // ์‚ญ์ œ ํ•˜๊ฒŒ ๋œ๋‹ค. ๊ฒฐ๊ณผ ์ ์œผ๋กœ a์™€ c๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋˜ ๊ณณ์ด ๋‘๋ฒˆ ์‚ญ์ œ ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒ๋œ๋‹ค. (a๊ฐ€ ์†Œ๋ฉธํ• ๋•Œ, c๊ฐ€ ์†Œ๋ฉธํ• ๋•Œ)
์ด์ƒ ์น˜ํ™˜ ์—ฐ์‚ฐ์ž์— ๊ด€ํ•œ๊ฒƒ.
...

์ดํ•˜ ๋ณต์‚ฌ ์ƒ์„ฑ์ž์— ๊ด€ํ•œ๊ฒƒ.
~cpp 
void doNothing(String localString) {}
...
String s = "The Truth Is Out There";
doNothing(s);  // deault ๋ณต์‚ฌ ์ƒ์„ฑ์ž ํ˜ธ์ถœ. call-by-value๋กœ ์ธํ•ด 
                 // localString์€ s์•ˆ์— ์žˆ๋Š” ํฌ์ธํ„ฐ์— ๋Œ€ํ•œ ๋ณต์‚ฌ๋ณธ์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.
// ๊ทธ๋ž˜์„œ, doNothing์ด ์ˆ˜ํ–‰์„ ๋งˆ์น˜๋ฉด, localString์€ ์—ฌ์—ญ์„ ๋ฒ—์–ด๋‚˜๊ณ , ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
// ๊ทธ ๊ฒฐ๊ณผ s๋Š” localString์ด ์‚ญ์ œํ•œ ๋ฉ”๋ชจ๋ฆฌ์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค. (data ์†์‹ค)
* ํด๋ž˜์Šค ์•ˆ์— ํฌ์ธํ„ฐ๋ฅผ ์กฐ๋ฌผ๋”ฑ ๊ฑฐ๋ฆฌ๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ์—๋Š” ๊ทธ ํด๋ž˜์Šค์— ๋ณต์‚ฌ ์ƒ์„ฑ์ž์™€, ์น˜ํ™˜ ์—ฐ์‚ฐ์ž๋ฅผ ๊ผญ ์ •์˜ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค...

3.2. Item 12: Prefer initialization to assignment in constructors

~cpp 
template<class T>
class NamedPtr {
public:
  NamedPtr(const string& initName, T *initPtr);
  ...

private:
  string name;
  T *ptr;
};
๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ๋ฐฉ๋ฒ•.


1. ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
~cpp 
template<class T>
NamedPtr<T>::NamedPtr(const string& initName, T *initPtr  )
: name(initName), ptr(initPtr) {}
2. ์ƒ์„ฑ์ž์˜ ์ฝ”๋“œ ๋ถ€๋ถ„์—์„œ ์น˜ํ™˜์„ ํ•œ๋‹ค.
~cpp 
template<class T>
NamedPtr<T>::NamedPtr(const string& initName, T *initPtr)
{
  name = initName;
  ptr = initPtr;
}
2๊ฐ€์ง€ ๋ฐฉ๋ฒ• ์ •๋„๋กœ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ• ์ˆ˜ ์žˆ๋Š”๋ฐ. ์ฑ…์—์„œ๋Š” ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ๋ฅผ ์„ ํ˜ธํ•œ๋‹ค.

์ฒซ์งธ๋Š” ์ดˆ๊ธฐํ™”๋งŒ ๊ฐ€๋Šฅํ•œ const๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ• ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์—์„œ์ด๊ณ ,

๋‘๋ฒˆ์งธ๋Š” ์‹ค์šฉ์ฃผ์˜(ํšจ์œจ์„ฑ) ์ฐจ์›์—์„œ ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ๋ฅผ ์„ ํ˜ธ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

(์™œ.. ํšจ์œจ์„ฑ์ด ์ข‹์•„์ง€๋Š”์ง€๋Š” ๊ฐ์ž ์ƒ๊ฐ~ ์ฑ…์—๋„ ๋‚˜์™€์žˆ๊ณ .. ์ƒ๊ฐ๋งŒ ํ•ด๋ณด๋ฉด ์•Œ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ~)


''
  • ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ํ•ญ์ƒ ๋ฉค๋ฒ„ ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์Šต๊ด€์„ ๋“ค์ด๋ฉด, const์™€ ๋ ˆํผ๋Ÿฐ์Šค ๋ณ€์ˆ˜๋“ค์— ๋Œ€ํ•œ
    ์š”๊ตฌ ์กฐ๊ฑด์„ ์ฑ„์šธ ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์— ๋Œ€ํ•œ ๋น„ํšจ์œจ์ ์ธ ์ดˆ๊ธฐํ™”๋„ ์ค„์ผ์ˆ˜ ์žˆ๋‹ค.''

3.3. Item 13: List members in an initialization list in the order in which they are declared

ํด๋ž˜์Šค ๋ฉค๋ฒ„๋“ค์€ ํด๋ž˜์Šค์— ์„ ์–ธ๋œ ์ˆœ์„œ์— ๋”ฐ๋ผ ์ดˆ๊ธฐํ™”๋œ๋‹ค.

๋ฉค๋ฒ„ ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ์— ๋‚˜์—ด๋œ ์ˆœ์„œ๋Š” ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ๋„ ๋ฏธ์น˜์ง€ ๋ชปํ•œ๋‹ค.

๋งŒ์•ฝ, ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ์— ๋‚˜์—ด๋œ ์ˆœ์„œ๋Œ€๋กœ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๊ฐ€ ์ดˆ๊ธฐํ™” ๋œ๋‹ค๊ณ  ๊ฐ€์ • ํ•˜๊ณ  ์ด ์˜ˆ๋ฅผ ๋ณด์ž.

~cpp 
class Wacko {
public:
  Wacko(const char *s): s1(s), s2(0) {}
  Wacko(const Wacko& rhs): s2(rhs.s1), s1(0) {}

private:
  string s1, s2;
};

Wacko w1 = "Hello world!";
Wacko w2 = w1;
w1๊ณผ w2์˜ ๋ฉค๋ฒ„๋“ค์€ ๋‹ค๋ฅธ ์ˆœ์„œ์— ๋”ฐ๋ผ ์ƒ์„ฑ๋  ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ , ๋‹ค์‹œ ๊ทธ ๊ฐ์ฒด๋“ค(string ๊ฐ์ฒด)์„ ์†Œ๋ฉธํ•˜๊ธฐ ์œ„ํ•ด์„œ

๊ฐ์ฒด๋“ค(string ๊ฐ์ฒด)์ด ์ƒ์„ฑ๋œ ์ˆœ์„œ๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค์Œ ์†Œ๋ฉธ์ž๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ํ˜ธ์ถœํ•ด์•ผ ํ• ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฐ overhead๋ฅผ ์—†์• ๊ธฐ ์œ„ํ•ด,

๋ชจ๋“  ๊ฐ์ฒด์— ๋Œ€ํ•ด์„œ ์ƒ์„ฑ์ž์™€ ์†Œ๋ฉธ์ž์˜ ํ˜ธ์ถœ ์ˆœ์„œ๋Š” ๋™์ผํ•˜๊ฒŒ ๋˜์–ด ์žˆ๊ณ , ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ์— ๋‚˜์—ด๋œ ์ˆœ์„œ๋Š” ๋ฌด์‹œ๋œ๋‹ค.

๋‹จ, ์ด๋Ÿฐ ๊ทœ์น™์€ ๋น„์ •์  ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋“ค๋งŒ ๋”ฐ๋ฅธ๋‹ค.

์ •์  ๋ฐ์ดํ„ฐ ๋“ค์ด์•ผ ๋‹จ์ง€ ํ•œ๋ฒˆ๋งŒ ์ดˆ๊ธฐํ™” ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ๊ฒƒ์„ ๋”ฐ๋ฅผ ํ•„์š”๋Š” ์—†๋‹ค.

3.4. Item 14: Make sure base classes have virtual destructors

๋ฒ ์ด์Šค ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž๋ฅผ ๊ฐ€์ƒํ•จ์ˆ˜๋กœ ๋‘”๋‹ค๋Š” ์–˜๊ธฐ๋Š” ๋ฒ ์ด์Šค ํด๋ž˜์Šค๊ฐ€ ๊ณ„์Šน ๋ ๊ฒฝ์šฐ ๊ณ„์Šน๋œ ํด๋ž˜์Šค์—๋‚ด์—์„œ ์†Œ๋ฉธ์ž์˜

์ž‘์šฉ์„ ์˜ฌ๋ฐ”๋กœ ํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค. ์ ๋‹นํ•œ ์˜ˆ๋ฅผ ๋ณด๋„๋ก ํ•˜์ž.

~cpp 
// base class
class EnemyTarget {
public:
  EnemyTarget() { ++numTargets; }
  EnemyTarget(const EnemyTarget&) { ++numTargets; }
  ~EnemyTarget() { --numTargets; }
  static unsigned int numberOfTargets()
  { return numTargets; }
  virtual bool destroy();                 // EnemyTarget ๊ฐ์ฒด ํŒŒ๊ดด์—
                                          // ์„ฑ๊ณตํ•˜๋ฉด ์ฐธ์„ ๋Œ๋ ค ์ค€๋‹ค

private:
  static unsigned int numTargets;               // ๊ฐ์ฒด ์นด์šดํ„ฐ
};
// class๋‚ด์˜ ์ •์  ๋ณ€์ˆ˜๋Š” ํด๋ž˜์Šค์˜ ๋ฐ”๊นฅ์ชฝ์— ์ •์˜๋˜์–ด์•ผ ํ•œ๋‹ค.
// ๊ธฐ๋ณธ์ ์œผ๋กœ 0์œผ๋กœ ์ดˆ๊ธฐํ™”๋œ๋‹ค.
unsigned int EnemyTarget::numTargets;
...
..
// base class๋ฅผ ์ƒ์†ํ•œ ํด๋ž˜์Šค
class EnemyTank: public EnemyTarget {
public:
  EnemyTank() { ++numTanks; }
  EnemyTank(const EnemyTank& rhs)
  : EnemyTarget(rhs)
  { ++numTanks; }
  ~EnemyTank() { --numTanks; }
  static unsined int numberOfTanks()
  { return numTanks; }
  virtual bool destroy();
private:
  static unsigned int numTanks;         // object counter for tanks
};
unsigned int EnenyTank::numTanks;
EnemyTarget์˜ ๊ฐ์ฒด๋ฅผ ์นด์šดํŠธ ํ•˜๊ธฐ ์œ„ํ•ด ์ •์  ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ numTargets๋ฅผ ๋‘์—ˆ์œผ๋ฉฐ EnemyTarget์„ ์ƒ์†ํ•œ EnemyTank์—์„œ๋„

๊ฐ์ฒด์˜ ์นด์šดํŠธ๋ฅผ ์œ„ํ•ด ์ •์  ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ numTanks๋ฅผ ๋‘์—ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณค, ๋‹ค์Œ๊ณผ ๊ฐ™์€ code๋ฅผ ์ ์šฉ์‹œ์ผœ๋ณด์ž.
~cpp 
EnemyTarget *targetPtr = new EnemyTank;
...
delete targetPtr;  // ์•„๋ฌด ๋ฌธ์ œ๊ฐ€ ์—†์–ด ๋ณด์ธ๋‹ค.
The C++ language standard is unusually clear on this topic. ๋ฒ ์ด์Šค ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ณ„์Šน๋œ ํด๋ž˜์Šค๋ฅผ

์‚ญ์ œํ•˜๋ ค๊ณ  ํ•˜๋ฉฐ, ๋ฒ ์ด์Šค ํด๋ž˜์Šค๋Š” ๊ฐ€์ƒ ์†Œ๋ฉธ์ž๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ. ๊ทธ ๊ฒฐ๊ณผ๋Š” ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค. ์ด๊ฒƒ์€ ์ปดํŒŒ์ผ๋Ÿฌ๋กœ

ํ•˜์—ฌ๊ธˆ, ์›ํ•˜๋Š” ๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์ƒ์ƒํ—ˆ๊ณ  ์‹คํ–‰ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•œ๋‹ค. (์‹คํ–‰ ์‹œ๊ฐ„์— ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์€ ๊ณ„์Šน๋œ ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž๊ฐ€

ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์œ„์˜ ์˜ˆ์—์„œ, targetPtr์ด ์‚ญ์ œ ๋ ๋•Œ EnemyTank์˜ ์ˆ˜๊ฐ€ ์ œ๋Œ€๋กœ ์กฐ์ •๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธ ํ•œ๋‹ค.)

๊ทธ๋ž˜์„œ ์ด๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ, EnemyTarget์˜ ์†Œ๋ฉธ์ž๋ฅผ virtual๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค. ์†Œ๋ฉธ์ž๋ฅผ ๊ฐ€์ƒํ•จ์ˆ˜๋กœ ์„ ์–ธํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์ด ์›ํ•˜๋Š”

๋ฐฉ์‹์œผ๋กœ ์†Œ๋ฉธ์ž๊ฐ€ ๋ถˆ๋ฆฌ๋„๋ก ํ• ์ˆ˜ ์žˆ๋‹ค.

3.5. Item 15: Have operator= return a reference to *this

์šฐ๋ฆฌ๋Š” ์šฐ์„  operator=๋ฅผ ์ •์˜ ํ•ด์ค„๋•Œ
~cpp 
w = x= y = z = "Hello"; 
์ด ๋Ÿฐ์‹์˜ ์—ฐ์†์ ์ธ ์น˜ํ™˜ ์—ฐ์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— operator=์—ฐ์‚ฐ์ž์˜ ๋ฆฌํ„ดํ˜•์„ void๋กœ ์ •์˜ ํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

๊ทธ๋ฆฌ๊ณ , operator=์—ฐ์‚ฐ์ž์˜ ๋ฆฌํ„ดํ˜•์„ const๋กœ ์ •์˜ ํ•ด ์ฃผ์—ˆ์„๋•Œ. ๋ฐ‘์˜ ์˜ˆ์ œ์™€ ๊ฐ™์€ ๋ฉ์ฒญํ•œ(?) ์—ฐ์‚ฐ์„ ํ•ด์ฃผ์—ˆ์„๋•Œ ์ ์šฉ ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐ‘์˜ ์—ฐ์‚ฐ์€ ๋ฉ์ฒญํ•œ(?) ์—ฐ์‚ฐ์ด์ง€๋งŒ C++์˜ ๊ธฐ๋ณธ ํƒ€์ž…์— ๋Œ€ํ•ด ์ €๋Ÿฐ ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ €๋Ÿฐ ์—ฐ์‚ฐ๋„ ์ง€์›ํ•˜๊ฒŒ ๋” ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
~cpp 
class Widget {
public:
  ...                                            // note
  const Widget& operator=(const Widget& rhs);    // const
  ...                                            // return
};                                               // type
...
Widget w1, w2, w3;
...
(w1 = w2) = w3;         // assign w2 to w1, then w3 to
                        // the result! (Giving Widget's
                        // operator= a const return value
                        // prevents this from compiling.)

๊ทธ๋ž˜์„œ, operator=์˜ ๋ฆฌํ„ดํ˜•์„ const๋กœ ์ž‘์„ฑํ•˜๋ฉด ์•ˆ๋œ๋‹ค. (....--;...)

...

๊ธฐ๋ณธ ํ˜•์‹์„ ๊ฐ–๋Š” ์น˜ํ™˜ ์—ฐ์‚ฐ์ž์—์„œ, ๋ฆฌํ„ด๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์น˜ํ™˜์˜ ์™ผ์ชฝ ๋ถ€๋ถ„ (this)๊ณผ ์น˜ํ™˜์˜ ์˜ค๋ฅธ์ชฝ ๋ถ€๋ถ„(์ธ์ž ๋ฆฌ์ŠคํŠธ์— ์žˆ๋Š”๊ฒƒ)์ด๋‹ค. ์–ด๋–ค๊ฒƒ์„ ๋ฆฌํ„ดํ•ด ์ค„๊ฒƒ์ธ๊ฐ€? operator=๊ณผ ๊ด€๋ จ๋œ ๋ฐ‘์˜ ๋‘๊ฐ€์ง€ ๊ฒฝ์šฐ๋ฅผ ๋ณด์ž.
~cpp 
String& String::operator=(const String& rhs)
{
  ...
  return *this;            // return reference
                           // to left-hand object
}
String& String::operator=(const String& rhs)
{
  ...
  return rhs;              // return reference to
                           // right-hand object
}
์œ„์˜ ๋‘๊ฐ€์ง€ ๊ฒฝ์šฐ๋Š” ๋ณ„๋‹ค๋ฅธ ์ฐจ์ด๊ฐ€ ์—†์–ด๋ณด์ธ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ์ค‘์š”ํ•œ ์ฐจ์ด์ ์ด ์žˆ์œผ๋‹ˆ ๋ง์„ ๊บผ๋‚ด๋Š” ๊ฒƒ์ด ๊ฒ ์ง€? --;

์ฒซ์งธ, rhs๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒฝ์šฐ๋Š” compile ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด, rhs๋Š” const String์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค ์ด๊ณ , operator=๋Š” String์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ฆฌํ„ดํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ญ ์ด๋Ÿฐ ๋ฌธ์ œ์•ผ ๋ฐ‘์—์„œ ์ฒ˜๋Ÿผ ๊ณ ์น˜๋ฉด ๋ฌธ์ œ ๋˜์ง€ ์•Š๋Š”๋‹ค.
~cpp 
String& String::operator=(String& rhs)   { ... }
ํ•˜์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” ํด๋ž˜์Šค์˜ operator=๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
~cpp 
x = "Hello";
์น˜ํ™˜์˜ ์˜ค๋ฅธ์ชฝ ๋ถ€๋ถ„์ด Stringํ˜•์ด ์•„๋‹ˆ๋ผ char *ํ˜•์ด๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ๋Ÿฌ๋Š” String์˜ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ž„์‹œ String๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ ํ˜ธ์ถœ์„ ํ•œ๋‹ค. ์ฆ‰, ์•„๋ž˜์™€ ๊ฐ™์€ code๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
~cpp 
const String temp("Hello"); // ์ž„์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.
...
x = temp; // ์ž„์‹œ ๊ฐ์ฒด๋ฅผ operator=์— ์ „๋‹ฌํ•œ๋‹ค.
์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์œ„์™€ ๊ฐ™์€ ์ž„์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜์ง€๋งŒ, ์ž„์‹œ ๊ฐ์ฒด๊ฐ€ const๋ผ๋Š” ๊ฒƒ์— ์ฃผ์˜. ๊ทธ๋ฆฌ๊ณ , operator=์˜ ๋ฆฌํ„ดํ˜•์„ ๋ณด๋ฉด String์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋Œ๋ ค์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌํ„ดํ˜•์ด ์ผ์น˜ํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ, error๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. ๋งŒ์•ฝ error๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค๋ฉด, operator=์ด ํ˜ธ์ถœ๋˜๋Š” ์ธก์—์„œ ์ œ๊ณต๋œ ์ธ์ž๊ฐ€ ์•„๋‹ˆ๋ผ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ์‹œํ‚จ ์ž„์‹œ ๋ณ€์ˆ˜๋งŒ ์ˆ˜์ •๋œ๋‹ค๋Š” ๊ฒƒ์— ๋†€๋ž„๊ฒƒ์ด๋‹ค. --;

..
๊ฒฐ๋ก ์„ ์–˜๊ธฐ ํ•˜์ž๋ฉด, ์น˜ํ™˜์˜ ์™ผ์ชฝ ๋ถ€๋ถ„์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค *this๋ฅผ ๋˜๋Œ๋ ค ์ฃผ๋„๋ก ์น˜ํ™˜ ์—ฐ์‚ฐ์ž๋ฅผ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค. ๋งŒ์ผ ์ด์™ธ์˜ ์ผ์„ ํ•˜๋ฉด, ์—ฐ์†์ ์ธ ์น˜ํ™˜์„ ํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜๊ณ , ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ์—์„œ์˜ ๋ฌต์‹œ์ ์ธ ํƒ€์ž… ๋ณ€ํ™˜๋„ ํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.

3.6. Item 16: Assign to all data members in operator=

operator= ์—ฐ์‚ฐ์ž๋ฅผ ์ˆ˜ํ–‰ํ• ๋•Œ ๊ฐœ์ฒด ๋‚ด ๊ฐ๊ฐ์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋ฅผ ์น˜ํ™˜ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค๋Š” ์–˜๊ธฐ.



์ƒ์†์˜ ๊ฒฝ์šฐ ํŠนํžˆ๋‚˜ ์กฐ์‹ฌํ•ด์„œ operator= ์—ฐ์‚ฐ์ž๋ฅผ ๋งŒ๋“ค์–ด ์ค˜์•ผ ํ•œ๋‹ค.
~cpp 
class Base {
public:
  Base(int initialValue = 0): x(initialValue) {}
private:
  int x;
};
class Derived: public Base {
public:
  Derived(int initialValue)
  : Base(initialValue), y(initialValue)   {}
  Derived& operator=(const Derived& rhs);
private:
  int y;
};

// The logical way to write Derived's assignment operator is like this 
// erroneous assignment operator
Derived& Derived::operator=(const Derived& rhs)
{
  if (this == &rhs) return *this;    
  
  y = rhs.y;                         // assign to Derived's
                                     // lone data member
  return *this;                      // see Item 15
}

// Unfortunately, this is incorrect, because the data member x in 
// the Base part of a Derived object is unaffected by this assignment operator. 
// For example, consider this code fragment 
void assignmentTester()
{
  Derived d1(0);                      // d1.x = 0, d1.y = 0
  Derived d2(1);                      // d2.x = 1, d2.y = 1
  d1 = d2;			 // d1.x = 0, d1.y = 1!
}
๋ณด๊ธฐ์™€ ๊ฐ™์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” operator= ์—ฐ์‚ฐ์ž์ด๋‹ค. ๊ทธ๋Ÿผ, ์ด๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ๊ณ ์น˜๋ฉด ์ข‹์„๊นŒ? ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ๋‹ค์Œ๊ณผ ๊ฐ™์ด Baseํด๋ž˜์Šค์˜ operator=์—ฐ์‚ฐ์ž๋ฅผ ํ˜ธ์ถœํ•ด ์ฃผ๋ฉด ๋œ๋‹ค. ( Derived ํด๋ž˜์Šค์˜ operator= ์—ฐ์‚ฐ์ž์—์„œ x๋ฅผ ์น˜ํ™˜ํ•ด ์ค€๋‹ค๋Š” ๊ฒƒ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—.)
~cpp 
// correct assignment operator
Derived& Derived::operator=(const Derived& rhs)
{
  if (this == &rhs) return *this;
  Base::operator=(rhs);    // call this->Base::operator=
  y = rhs.y;
  return *this;
}


์ƒ์†๊ณผ ๊ด€๋ จํ•˜์—ฌ ์œ ์‚ฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ณต์‚ฌ ์ƒ์„ฑ์ž์—์„œ๋„ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ๋ฐ‘์˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.
~cpp 
class Base {
public:
  Base(int initialValue = 0): x(initialValue) {}
  Base(const Base& rhs): x(rhs.x) {}
private:
  int x;
};
class Derived: public Base {
public:
  Derived(int initialValue)
  :  Base(initialValue), y(initialValue) {}
  Derived(const Derived& rhs)      // erroneous copy
  : y(rhs.y) {}                    // constructor
private:
  int y;
};
Derived ํด๋ž˜์Šค์˜ ๋ณต์‚ฌ ์ƒ์„ฑ์ž๋ฅผ ๋ณด๋ฉด Baseํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” ์ดˆ๊ธฐํ™” ์‹œํ‚ค์ง€ ์•Š์Œ์„ ์•Œ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ‘์˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด Baseํด๋ž˜์Šค์˜ ๋ณต์‚ฌ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด ์ฃผ๋ฉด ๋œ๋‹ค.
~cpp 
class Derived: public Base {
public:
  Derived(const Derived& rhs): Base(rhs), y(rhs.y) {}
  ...
};
์ด์   Derivedํด๋ž˜์Šค์˜ ๋ณต์‚ฌ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด๋„ Baseํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์—ญ์‹œ ์ž˜ ๋ณต์‚ฌ ๋œ๋‹ค.

3.7. Item 17: Check for assignment to self in operator=

assignment to self in operator= (์žฌ๊ท€์น˜ํ™˜) ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์„๋•Œ ๋ฐœ์ƒํ•œ๋‹ค.
~cpp 
class X { ... };
X a;
a = a;                     // a is assigned to itself
'์™œ ์ด๋Ÿฐ ๋Œ€์ž…์„ ํ•˜๋Š”๊ฑฐ์ง€. ํ”„๋กœ๊ทธ๋žจ ์งœ๋Š” ๋†ˆ์ด ๋ฐ”๋ณด ์ธ๊ฐ€?' ๋ผ๋Š” ์ƒ๊ฐ์„ ํ•  ์ˆ˜ ๋„์žˆ์ง€๋งŒ, ๋ฐ‘์˜ ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž.
~cpp 
a = b
๊ทธ๋Ÿฐ๋ฐ b๊ฐ€ a๋กœ ์ดˆ๊ธฐํ™”๋œ ๋ ˆํผ๋Ÿฐ์Šค๋ผ๋ฉด ๋ณด๊ธฐ์—๋Š” ์žฌ๊ท€์น˜ํ™˜์— ํ•ด๋‹นํ•œ๋‹ค. ์ด๋Ÿฐ ๊ฐ€๋Šฅํ•œ ์ƒํ™ฉ์— ๋Œ€์ฒ˜ํ•˜๊ธฐ ์œ„ํ•ด ํŠน๋ณ„ํžˆ ์ฃผ์˜๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ์— ๋Š” ๋‘๊ฐ€์ง€ ์ข‹์€ ์ ์ด ์žˆ๋‹ค. ์ฒซ์งธ๋Š” ํšจ์œจ์„ฑ์ด๋‹ค. ์น˜ํ™˜ ์—ฐ์‚ฐ์ž์˜ ์ƒ์œ„ ๋ถ€๋ถ„์—์„œ ์žฌ๊ท€์น˜ํ™˜์„ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๋ฐ”๋กœ ๋ฆฌํ„ดํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋‘๋ฒˆ์งธ๋Š”, ์ •ํ™•ํ•จ์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์น˜ํ™˜ ์—ฐ์‚ฐ์ž๋Š” ๊ฐ์ฒด์˜ ์ƒˆ๋กœ์šด ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค๋“ค์„ ํ• ๋‹นํ•˜๊ธฐ ์ „์— ๊ฐ์ฒด์— ํ• ๋‹น๋œ ๋ฆฌ์†Œ์Šค๋“ค์„ ํ•ด์ œํ•ด์•ผ๋งŒ ํ•œ๋‹ค. ์ด์ „ ๊ฐ’๋“ค์„ ์ œ๊ฑฐํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋ง์ด๋‹ค. ์žฌ๊ท€์น˜ํ™˜์ผ ๊ฒฝ์šฐ ์ด๋Ÿฐ์‹์œผ๋กœ ์ด์ „ ๊ฐ’๋“ค์„ ์ œ๊ฑฐํ• ๊ฒฝ์šฐ ํฐ hazard๋ฅผ ๊ฐ€์ ธ ์˜จ๋‹ค. ์™œ๋ƒํ•˜๋ฉด, ๊ธฐ์กด ๋ฆฌ์†Œ์Šค๋“ค์ด ์ƒˆ๋กœ์šด ๋ฆฌ์†Œ๋“ค์„ ์น˜ํ™˜ํ•˜๋Š” ๊ณผ์ •์—์„œ ํ•„์š”ํ•˜๊ฒŒ ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.




String ๊ฐ์ฒด๋“ค์˜ ์น˜ํ™˜์„ ์ƒ๊ฐํ•ด ๋ณด์ž. ์—ฌ๊ธฐ์—์„  ์žฌ๊ท€์น˜ํ™˜์„ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค.
~cpp 
class String {
public:
  String(const char *value);    // see Item 11 for
                                // function definition
  ~String();                    // see Item 11 for
                                // function definition
  ...
  String& operator=(const String& rhs);
private:
  char *data;
};

// an assignment operator that omits a check
// for assignment to self
String& String::operator=(const String& rhs)
{
  delete [] data;    // delete old memory

  // allocate new memory and copy rhs's value into it
  data =   new char[strlen(rhs.data) + 1];
  strcpy(data, rhs.data);
  return *this;      // see Item 15
}
๊ทธ๋ฆฌ๊ณ , ์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ๋ฅผ ๋ณด์ž.
~cpp 
String a = "Hello";

a = a;               // same as a.operator=(a)
String๊ฐ์ฒด์˜ operator= ์—ฐ์‚ฐ์ž๋ฅผ ๋ณผ๋•Œ *this์™€ rhs๋Š” ๋‹ค๋ฅธ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ์ด ๋‘˜์€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ pointingํ•˜๊ณ  ์žˆ๋‹ค. (๊ฐ™์€ ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์—..)



์น˜ํ™˜ ์—ฐ์‚ฐ์ž๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ž‘์—…์ด data๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ, ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.





์ด์ œ ์น˜ํ™˜์—ฐ์‚ฐ์ž์—์„œ strcpy๋ฅผ ์ˆ˜ํ–‰ํ• ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ผ์€ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด๊ฒƒ์€ data๊ฐ€ ์‚ญ์ œ๋˜๋ฉด์„œ rhs.data๊ฐ€ ์‚ญ์ œ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๊ฒƒ์€ data, this->data ๊ทธ๋ฆฌ๊ณ , rhs.data๊ฐ€ ๋ชจ๋‘ ๊ฐ™์€ ํฌ์ธํ„ฐ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๊ฒŒ ๋œ๊ฒƒ์ด๋‹ค. ์ตœ์•…์˜ ์ƒํ™ฉ์ด๋‹ค..


์ด์ œ ์™œ? ์žฌ๊ท€์น˜ํ™˜์„ ๊ฒ€์‚ฌํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ์•˜์„ ๊ฒƒ์ด๋‹ค.




๊ทธ๋Ÿผ, ์–ด๋–ค์‹์œผ๋กœ ์žฌ๊ท€์น˜ํ™˜์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ๊ฒ€์‚ฌํ• ๊นŒ? ์ข…๋ฅ˜๋Š” ๋‹ค์–‘ํ•˜๋‹ค.
~cpp 
// data์˜ ๋™์ผ์„ฑ์„ ๊ฒ€์‚ฌ
String& String::operator=(const String& rhs)
{
  if (strcmp(data, rhs.data) == 0) return *this;
  ...
}

// ๊ฐ์ฒด์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์˜ ๊ฐ’์ด ๋™์ผํ•œ์ง€ ๊ฒ€์‚ฌ
// ์ด๋•Œ operator== ์„ ๋‹ค์‹œ ์žฌ์ •์˜ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค
C& C::operator=(const C& rhs)
{
  // check for assignment to self
  if (*this == rhs)              // assumes op== exists
    return *this;
  ...
}

// ์ฃผ์†Œ๊ฐ’์„ ํ†ตํ•œ ๊ฒ€์‚ฌ - ๊ฐ€์žฅ ์ข‹์€ ํšจ๊ณผ๋ฅผ ๊ธฐ๋Œ€ํ• ๋งŒ ํ•˜๋‹ค.
C& C::operator=(const C& rhs)
{
  // check for assignment to self
  if (this == &rhs) return *this;
  ...
}

// ํด๋ž˜์Šค๋งˆ๋‹ค ์‹๋ณ„์ž๋ฅผ ๋‘์–ด ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ๋ฒ•
// ์ด๊ฒฝ์šฐ์—๋„ operator == ์„ ์ •์˜ํ•˜์—ฌ ์‹๋ณ„์ž๊ฐ€ ๊ฐ™์€์ง€ ๊ฒ€์‚ฌํ•ด๋ณด์•„์•ผ ํ•œ๋‹ค.
class C {
public:
  ObjectID identity() const;            // see also Item 36
  ...
};

4. Classes and Functions: Design and Declaration

ํšจ๊ณผ์ ์ธ ํด๋ž˜์Šค ์„ค๊ณ„๋ž€ ๋ฌด์—‡์ธ๊ฐ€? ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ถ€๋ถ„

1. ๊ฐ์ฒด๋“ค์ด ์–ด๋–ป๊ฒŒ ์ƒ์„ฑ๋˜๊ณ  ์†Œ๋ฉธ๋  ๊ฒƒ์ธ๊ฐ€?

2. ๊ฐ์ฒด ์ดˆ๊ธฐํ™”์™€ ๊ฐ์ฒด ์น˜ํ™˜์ด ์–ด๋А ์ •๋„ ์ฐจ์ด๊ฐ€ ๋‚˜๋Š”๊ฐ€?

3. ์ƒˆ๋กœ์šด ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๊ฐ’์— ์˜ํ•ด ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ๋ฌด์—‡์„ ์˜๋ฏธ ํ•˜๋Š”๊ฐ€?

4. ์ƒˆ๋กœ์šด ํƒ€์ž…์˜ ๊ฐ์ฒด๊ฐ€ ์ƒ์† ๊ทธ๋ž˜ํ”„์— ๋งž๋Š”๊ฐ€?

5. ์–ด๋–ค ์ข…๋ฅ˜์˜ ํƒ€์ž… ๋ณ€ํ™˜์ด ํ—ˆ์šฉ๋˜๋Š”๊ฐ€?

6. ์–ด๋–ค ์—ฐ์‚ฐ์ž์™€ ํ•จ์ˆ˜๊ฐ€ ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ์œ„ํ•ด ์ ๋‹นํ•œ๊ฐ€?

7. ์ ‘๊ทผ ์—ฐ์‚ฐ์ž(public, protected, private)๋ฅผ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•  ๊ฒƒ์ธ๊ฐ€?

8. etc..

4.1. Item 18. ์ตœ์†Œํ•œ์˜ ์™„์ „ํ•œ ํด๋ž˜์Šค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ถ”๊ตฌํ•œ๋‹ค.

interface? ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ ‘๊ทผํ• ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์„ ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ•จ์ˆ˜๋“ค๋งŒ ์ด๋Ÿฌํ•œ ์ธํ„ฐํŽ˜์ด์Šค ๋‚ด์— ์กด์žฌํ•œ๋‹ค. ๋งŒ์•ฝ ํด๋ž˜์Šค๋‚ด์˜ ๋ฐ์ดํƒ€ ๋ณ€๋“ค์—๊ฒŒ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋งŽ์€ ๋‹จ์ ๋“ค์ด ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (๋ณ„๋กœ ๋А๋ผ์ง€๋Š” ๋ชปํ•ด ๋ดค๋‹ค.. ^^;)

์ตœ์†Œํ•œ์˜ ์™„์ „ํ•œ ํด๋ž˜์Šค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ถ”๊ตฌํ•œ๋‹ค(?) ์ด๋ง์€ ํด๋ž˜์Šค๋‚ด์— ๊ตฐ๋”๋”๊ธฐ ์ฆ‰ ๋น„์Šทํ•œ ์ผ์„ ํ•˜๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜๊ฐ€ ์กด์žฌ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ๋„ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ , ๊ทธ ํด๋ž˜์Šค๋Š” ๊ทธ๋งŒํผ ๋ณต์žกํ•˜์ง€์•Š์„ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ , ์ตœ์†Œํ•œ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ด ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋“  ์ผ(?)์„ ํ• ์ˆ˜๊ฐ€ ์žˆ์–ด์•ผํ•œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, ์™œ ์ตœ์†Œํ•œ์ธ๊ฐ€? ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ผ์„ ํ• ์ˆ˜ ์žˆ๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋“ค์„ ๊ณ„์† ์ถ”๊ฐ€ํ•ด ๋‚˜๊ฐ€๋ฉด ์•ˆ๋˜๋Š” ๊ฒƒ์ธ๊ฐ€? ๋Œ€๋‹ต์€ ์•ˆ๋œ๋‹ค. ์™œ ์•ˆ๋˜๋Š” ๊ฒƒ์ผ๊นŒ? ๋‹น์‹ ์€ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๊ฐ€ 10๊ฐœ ์žˆ๋Š” ํด๋ž˜์Šค์™€ 100๊ฐœ๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค์ค‘ ์–ด๋–ค๊ฒƒ์ด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”๊ฐ€? ๋‚˜ ๋งŒ ์“ฐ๋ ค๋Š” ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ์ด์ƒ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋“ค์ด ์‰ฝ๊ฒŒ ์ดํ•ด ํ• ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•˜์ง€ ์•Š๊ฒ ๋Š”๊ฐ€? ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์†Œํ•œ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ถ”๊ตฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ , ๊ด€๋ฆฌ์ ์ธ ๋ฉด์—์„œ ๋ณผ๋•Œ ์ ์€ ํ•จ์ˆ˜๋“ค์„ ๊ฐ€์ง„ ํด๋ž˜์Šค๊ฐ€ ์šฉ์ดํ•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ค‘๋ณต๋œ ์ฝ”๋“œ๋ผ๋˜์ง€ ์•„๋‹ˆ๋ฉด ๊ฐœ์„ ํ•  ๊ฒƒ๋“ค์„ ํ–ฅํ›„์— ํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋˜ํ•œ, document๋ฅผ ์ž‘์„ฑํ•œ๋‹ค ๋“ ์ง€ ํ• ๋•Œ ์ ์€ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋“ค์„ ๊ฐ€์ง„ ํด๋ž˜์Šค ์ชฝ์ด ์šฉ์ดํ•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ์•„์ฃผ ๊ธด ํด๋ž˜์Šค ์ •์˜๋Š” ๊ธด ํ—ค๋” ํŒŒ์ผ์„ ์ดˆ๋ž˜ ํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ—ค๋” ํŒŒ์ผ๋“ค์€ ํ”„๋กœ๊ทธ๋žจ์ด ์ปดํŒŒ์ผ๋  ๋•Œ๋งˆ๋‹ค ๋งค ๋ฒˆ ์ฝํ˜€์ ธ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š” ์ด์ƒ ๊ธด ํด๋ž˜์Šค ์ •์˜๋Š” ํ”„๋กœ์ ํŠธ ์ฃผ๊ธฐ ์ค‘์˜ ์ด ์ปดํŒŒ์ผ ์‹œ๊ฐ„์„ ๊ฐ‰์•„ ๋จน๋Š”๋‹ค. ๊ทธ๋Ÿฐ ์ด์œ ๋“ค ๋•Œ๋ฌธ์— ์ตœ์†Œํ•œ์˜ ํด๋ž˜์Šค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ถ”๊ตฌํ•˜๋Š” ๊ฒƒ์ด ์ข€๋” ๋‚˜์€ ํŒ๋‹จ์ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค.

4.2. Item 19. ๋ฉค๋ฒ„ ํ•จ์ˆ˜, ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜ ๋ฐ ํ”„๋ Œ๋“œ ํ•จ์ˆ˜๋ฅผ ๊ตฌ๋ณ„ํ•œ๋‹ค.

๋Œ€๊ฒŒ class๋‚ด์— operator ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์„œ ์ข€๋” ํŽธํ•œ code(?)๋ผ๋Š” ๊ฒƒ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์„ ์–ธ ํ•˜๋Š” ํ•จ์ˆ˜๋“ค์ด ๋ฉค๋ฒ„ ํ•จ์ˆ˜์—ฌ์•ผ ํ•˜๋Š”์ง€ ์•„๋‹ˆ๋ฉด friendํ•จ์ˆ˜์—ฌ์•ผ ํ•˜๋Š”์ง€๋ฅผ
์‘ฅ๋• ์‘ฅ๋• ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์˜ ์—ฐ์‚ฐ์„ ๋‹ค์–‘ํ•˜๊ฒŒ ์ ์šฉ์‹œํ‚ค๊ณ  ์‹ถ๋‹ค๋ฉด friend ํ•จ์ˆ˜๋ฅผ ์จ์„œ ์ผ๋ฐ˜ ์ƒ์ˆ˜๊ฐ€ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค์˜ ์™ผํŽธ์— ์ž๋ฆฌ ์žก๊ณ  ์žˆ์–ด๋„ ์—ฐ์‚ฐ์ด ๋˜๊ฒŒ ํ•˜๊ณ ์‹ถ๋‹ค๋ผ๋Š” ์ƒ๊ฐ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด friendํ•จ์ˆ˜๋ฅผ ์จ์„œ ๋น„ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๊ทธ ์—ฐ์‚ฐ์„ ์ง€์›ํ•˜๋ผ๋Š” ์–˜๊ธฐ ์ด๋‹ค.
~cpp 
Num a(10);
int temp;
temp = 2 * a; // ์ด๋Ÿฐ ์—ฐ์‚ฐ. - friendํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ์‚ฐ์ž๋ฅผ ์ •์˜ ํ•ด์ค˜์•ผ์ง€๋งŒ ์ž‘๋™ํ•œ๋‹ค.
๊ทธ๋ ‡์ง€๋งŒ, ์ด๋Ÿฐ ์—ฐ์‚ฐ์ž๋“ค์„ ๊ฑฐ์˜ ์•ˆ์“ฐ๋Š” ๊ฒƒ๊ฐ™๋‹ค.. ใ…กใ…ก; ๋‚˜๋„ friendํ•จ์ˆ˜ ์จ๋ณธ ์ผ์ด ์—†๋‹ค.. ใ…กใ…ก; ํ•™๊ต ์‹œํ—˜์—์„œ ๋‚˜์˜ฌ๋ฒ•ํ•œ ์–˜๊ธฐ๋“ค.


- tip -

์—ฌ๊ธฐ์„œ f๋Š” ์ ์ ˆํžˆ ์„ ์–ธํ•˜๊ณ ์ž ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ  C๋Š” ๊ฐœ๋…์ ์œผ๋กœ ๊ด€๋ จ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
  • operator>>์™€ operator<<๋Š” ๊ฒฐ์ฝ” ๋ฉค๋ฒ„๊ฐ€ ๋ ์ˆ˜ ์—†๋‹ค. ๋งŒ์ผ f๊ฐ€ operator>>๋˜๋Š” operator<<์ด๋ผ๋ฉด, f๋ฅผ ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ f๊ฐ€ C์˜ ๋น„๊ณต์šฉ ๋ฉค๋ฒ„๋กœ ์ ‘๊ทผ์ด ์š”๊ตฌ๋œ๋‹ค๋ฉด f๋ฅผ C์˜ ํ”„๋ Œ๋“œ๋กœ ๋งŒ๋“ ๋‹ค.
  • ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜๋“ค๋งŒ ๊ทธ๋“ค์˜ ๊ฐ€์žฅ ์™ผ์ชฝํŽธ์— ์žˆ๋Š” ์ธ์ž์—์„œ ํƒ€์ž… ๋ณ€ํ™˜์ด ์ผ์–ด๋‚œ๋‹ค. ๋งŒ์ผ f๊ฐ€ ๊ฐ€์žฅ ์™ผ์ชฝํŽธ์— ์žˆ๋Š” ์ธ์ž์—์„œ ํƒ€์ž… ๋ณ€ํ™˜์„ ํ•„์š”๋กœ ํ•œ๋‹ค๋ฉด f๋ฅผ ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ f๊ฐ€ C์˜ ๋น„๊ณต์šฉ ๋ฉค๋ฒ„์— ์ ‘๊ทผ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด f๋ฅผ C์˜ ํ”„๋ Œ๋“œ๋กœ ๋งŒ๋“ ๋‹ค.
  • ๊ทธ ๋ฐ–์— ๋ชจ๋“  ๊ฒƒ์€ ๋ฉค๋ฒ„ ํ•จ์ˆ˜์ด์–ด์•ผ ํ•œ๋‹ค. ์ด์ƒ์˜ ์–ด๋–ค ๊ฒƒ์—๋„ ํ•ด๋‹น๋˜์ง€ ์•Š์œผ๋ฉด f๋ฅผ C์˜ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ ๋‹ค.

4.3. Item 20. ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋ฅผ ๊ณต์šฉ(public) ์ธํ„ฐํŽ˜์ด์Šค์— ํฌํ•จ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.

์ œ๋ชฉ๊ทธ๋Œ€๋กœ.

4.4. Item 21. ๊ฐ€๋Šฅํ•œ const๋ฅผ ์ด์šฉํ•œ๋‹ค.

const๋ฅผ ์“ฐ๋Š” ์ด์œ ๋Š” ์š”๋†ˆ์˜ ๊ฐ’์€ ์ ˆ๋Œ€๋กœ ๋ณ€ํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค๋Š”๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•จ์ด๋ž„๊นŒ? ์•„๋ฌดํŠผ const๋กœ ์ง€์ •์„ ํ•ด๋†“์œผ๋ฉด ์–ด๋–ป๊ฒŒ ํ•˜๋“  ๊ทธ ๊ฐ’์€ ์ ˆ๋Œ€๋กœ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๋‹ค๋Š”๊ฒƒ์€ ๋ณด์žฅ์ด ๋œ๋‹ค.
~cpp 
const char *p = "Hello";
char * const p = "Hello";
const char * const p = "Hello"; 
// ์ด ์„ธ๊ฐ€์ง€์˜ ์ฐจ์ด์ ์€ ๋ญ˜๊นŒ์š”?
// ์ž˜ ์ƒ๊ฐ ํ•˜๋ฉด ์•Œ์ˆ˜ ์žˆ์„ ๊ฑฐ์—์š”.
// pointer๋ž€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ณณ์˜ ๊ฐ’๊ณผ, ์ฃผ์†Œ๋กœ ์ด๋ฃจ์–ด ์ง„ ๋†ˆ์ด๋‹ˆ๊นŒ.
// ์–ด๋–ค๋•Œ๋Š” ์ฃผ์†Œ๊ฐ€ ๋ณ€ํ•˜์ง€ ๋ง์•˜์œผ๋ฉด ํ• ๋•Œ์ด๊ณ ,
// ์–ด๋–ค๋†ˆ์€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ณณ์˜ ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ๋ง์•˜์œผ๋ฉด ํ• ๋•Œ.. ์ด๋Ÿฐ ์‹์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด ์‰ฌ์šธ๋“ฏ ํ•˜๋„ค์š”.. ใ…Žใ…Ž
.. ์ถ”ํ›„์— ์ •๋ฆฌ..

4.5. ํ•ญ๋ชฉ 22. ๊ฐ’์— ์˜ํ•œ ํ˜ธ์ถœ๋ณด๋‹ค๋Š” ๋ ˆํผ๋Ÿฐ์Šค์— ์˜ํ•œ ํ˜ธ์ถœ์„ ์„ ํ˜ธํ•œ๋‹ค.

์ด ํ•ญ๋ชฉ์€ ์ฐธ์กฐ๋ฅผ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์ด๋‹ค.
์ฒซ๋ฒˆ์งธ๋Š” ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด๊ฐ’์œผ๋กœ ์‚ฌ์šฉ์‹œ ๋ฌด๋ฆฌํ•˜๊ฒŒ ์ž„์‹œ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ์ด ๋  ์ˆ˜ ์žˆ๋‹ค.
{{|
class Person
{
...
private:
string name, address;
}
class Student : public Person
{
...
private:
string schoolName, schoolAddress;
}
|}}
์ด๋ ‡๊ฒŒ ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ
{{|
Student returnStudent(Student s)
{
return s;
}

...

Student plato;

returnStudent(plato);
|}}
์ด๋ ‡๊ฒŒ ํ˜ธ์ถœ์ด ๋œ๋‹ค๋ฉด

plato๋Š” returnStudentํ•จ์ˆ˜์—์„œ ์ธ์ž๋กœ ๋„˜์–ด๊ฐ€๋ฉด์„œ ์ž„์‹œ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๊ณ  ํ•จ์ˆ˜ ๋‚ด์— ์“ฐ์ด๋ฉด์„œ s๋กœ ๋˜ ํ•œ๋ฒˆ ์ƒ์„ฑ๋˜๊ณ  ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ์ด ๋˜๊ณ  ๋ฐ˜ํ™˜ ๋ ๋•Œ ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด๋ฅผ ์œ„ํ•ด ๋˜ ํ•œ๋ฒˆ ๋ณต์‚ฌ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
์ด 3๋ฒˆ์˜ ๋ถ€๊ฐ€์ ์ธ ํ˜ธ์ถœ์ด ์ผ์–ด๋‚˜๋ฉด์„œ ๋ฉค๋ฒ„์ธ string๋“ค์€ ์ด 12๋ฒˆ์ด๋‚˜ ์ƒ์„ฑ์ด๋˜๊ณ  ํŒŒ๊ดด๊ฐ€ ๋œ๋‹ค.

๋‘๋ฒˆ์งธ๋Š” ์ž˜๋ผ์ง€๋Š” ๋ฌธ์ œ(slicing problem)๋กœ ์œ„์˜ ์˜ˆ์—์„œ returnStudentํ•จ์ˆ˜์— ์ธ์ž๋กœ Personํ˜• ๊ฐ์ฒด๊ฐ€ ๋‹ค์šด ์บ์ŠคํŒ…ํ•ด์„œ ๋“ค์–ด๊ฐ€๋Š” ๊ฒฝ์šฐ ๋‚ด๋ถ€์ ์ธ ์ž„์‹œ๊ฐ์ฒด๋“ค์˜ ์ƒ์„ฑ์œผ๋กœ Studentํ˜• ๊ฐ์ฒด๋กœ ์ธ์‹๋˜ Studentํ˜• ๊ฐ์ฒด๋งŒ์˜ ๋ฉค๋ฒ„๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ๋˜๋ฉด ์ •์ƒ์ž‘๋™์„ ๋ณด์žฅํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.

4.6. ํ•ญ๋ชฉ 23. ๊ฐ์ฒด ๋ฐ˜ํ™˜์‹œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ฐ์ฒด ๋ฐ˜ํ™˜์€ ๊ฐ’์˜ ์˜ํ•œ ํ˜ธ์ถœ์ด ์ฐธ์กฐ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ„๋‹จํ•˜๊ณ  ๋ช…ํ™•ํ•˜๋‹ค.
๊ทธ๋ ‡์ง€ ์•Š๊ณ  ์ฐธ์กฐ์— ์˜ํ•œ ํ˜ธ์ถœ์„ ํ•  ๊ฒฝ์šฐ์— ์ฑ…์—์„œ๋Š” ๋‚ด๋ถ€ ์ž„์‹œ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๋ฐ˜ํ™˜์„ ํ•˜๋ ค๊ณ  ํ• ๋• ๊ทธ ์ž„์‹œ ๊ฐ์ฒด์˜ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์Šคํƒ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋˜๊ณ , new๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํž™ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค๋•Œ๋Š” ์—ฐ๋‹ฌ์— ์„ธ๋ฒˆ์˜ ํ˜ธ์ถœ์ด ์žˆ์„ ๊ฒฝ์šฐ ํ•„์—ฐ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ˆ„์ถœ๋œ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  static์˜ ์ •์  ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ์—๋„ ๋น„๊ต๋ฌธ(operator =)์—์„œ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด ์–ธ์ œ๊ฐ€ ์ฐธ์œผ๋กœ ๊ณ„์‚ฐ์ด ๋ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ์ •์  ๊ฐ์ฒด ๋ฐฐ์—ด๋กœ ๋ฌด๋ฆฌํ•ด์„œ ๊ตฌํ˜„์„ ํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ๊ทธ๊ฑด ๋ฐ”๋กœ ์‚ฝ์งˆ์ด๋‹ค.

4.7. ํ•ญ๋ชฉ 24. ํ•จ์ˆ˜ ์˜ค๋ฒ„๋กœ๋”ฉ๊ณผ ๋””ํดํŠธ ์ธ์ž๊ฐ’ ์ค‘์—์„œ ์ฃผ์˜๊นŠ๊ฒŒ ์„ ํƒํ•œ๋‹ค.

  • std::numeric_limits<TYPE>::min(); // ํ—ค๋” <limits> TYPE์˜ ์ตœ์†Œ๊ฐ’์„ ๊ตฌํ•ด์ค€๋‹ค. INT_MIN๊ณผ ๊ฐ™์€ ๊ฐ’.

๋””ํดํŠธ ์ธ์ž๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๊ณ  ์—†๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค๋ฉด 5๊ฐœ์˜ ๊ฐ’์˜ ํ‰๊ท ์„ ๋‚ธ๋‹ค๋˜๊ฐ€ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋””ํดํŠธ ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

์ž์‹ ์ด ์•Œ์•„์„œ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ฒ˜์‹ ํ•˜๋„๋ก.

4.8. ํ•ญ๋ชฉ 25. ํฌ์ธํ„ฐ๋‚˜ ์ˆ˜์น˜ํ˜• ํƒ€์ž…์ƒ์˜ ์˜ค๋ฒ„๋กœ๋”ฉ์„ ํ”ผํ•œ๋‹ค.

๋งŒ์•ฝ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ
{{|
void f(string *);
f(int);
..
f(0); // ์ •์ˆ˜ํ˜• 0์ด๋ฏ€๋กœ f(int)๊ฐ€ ํ˜ธ์ถœ
f(NULL); // ?-_-? ๊ต‰์žฅํžˆ ๋ณต์žก ๋ฏธ๋ฌ˜ํ•˜๋‹ค-_-; ์„ ์–ธ์— ๋”ฐ๋ผ์„œ 0์ด ๋ ์ˆ˜๋„ (void*)0์ด ๋ ์ˆ˜๋„ 0L์ด ๋ ์ˆ˜๋„ ๋“ฑ๋“ฑ์˜ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.
|}}
NULL์ด๋ผ๋Š” ์ƒ์ˆ˜์— ๋Œ€ํ•œ ํƒ€์ž…์˜ ์ •์˜๊ฐ€ ๋ชจํ˜ธํ•˜๋‹ค.

์ด๋Ÿฐ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
{{|
const class // ํด๋ž˜์Šค์˜ ์ด๋ฆ„์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.
{
public:
template<class T> operator T*() const // ๋ชจ๋“  NULL ํฌ์ธํ„ฐ๋ฅผ ๋Œ€์ฒดํ•œ๋‹ค.
{
return 0;
}
template
{
return 0;
}
private:
void operator&() const; // NULL์˜ ์ฃผ์†Œ๊ฐ’์ด๋ž€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค.
} NULL;
|}}
๊ฒฐ๋ก ์€ ๋˜๋„๋ก์ด๋ฉด ์ด๋ ‡๊ฒŒ ๋ณต์žกํ•˜๊ฒŒ ๋“ค์–ด๊ฐ€๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์œผ๋ฉด ๋œ๋‹ค.

4.9. ํ•ญ๋ชฉ 26. ์ž ์žฌ์  ๋ชจํ˜ธ์„ฑ์„ ๊ฒฝ๊ณ„ํ•œ๋‹ค.

  • ๋ˆ„๊ตฌ๋‚˜ ๋‚˜๋ฆ„๋Œ€๋กœ์˜ ์ฒ ํ•™์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค. ์–ด๋–ค ์ด๋Š” ๋ถˆ๊ฐ„์„ญ์ฃผ์˜ ๊ฒฝ์ œํ•™์„ ๋ฏฟ๊ณ  ์–ด๋–ค ์ด๋Š” ์œคํšŒ์„ค์„ ๋ฏฟ๋Š”๋‹ค. ๋˜ ์–ด๋–ค ์ด๋Š” COBOL์ด ์ง„์งœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ผ๊ณ  ๋ฏฟ๋Š”๋‹ค. C++๋„ ๋‚˜๋ฆ„์˜ ์ฒ ํ•™์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. C++๋Š” ์ž ์žฌ์ ์ธ ์• ๋งค๋ชจํ˜ธ์„ฑ์€ ์—๋Ÿฌ๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋‚˜๋Š” ๊ณผํ•™-๊ธฐ์ˆ  ์„œ์ ์—์„œ๋„ ์ด๋Ÿฌํ•œ ์ถฉ๋ถ„ํžˆ ๊นŠ์€ ์ƒ๊ฐ์˜ ์ด์•ผ๊ธฐ๋„ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

C++์–ธ์–ด๋Š” ์ž ์žฌ์ €์ธ ์• ๋งค๋ชจํ˜ธ์„ฑ์„ ๊ฐ€์ง„ ์–ธ์–ด์ด๋‹ค.
์ฑ…์—์„œ๋Š” ๋ช‡๊ฐ€์ง€ ์˜ˆ๋ฅผ ๋“ค๊ณ  ์žˆ๋‹ค.
{{|
void f(A);

...

B b;
f(b);
|}}
๋ฅผ ํ˜ธ์ถœ์‹œ ํ•จ์ˆ˜ f๋Š” ์ธ์ž๋กœ A๋ฅผ ์š”๊ตฌํ•œ๋‹ค. ์šฐ์„  B๊ฐ€ A์˜ ์ž์‹์ด๋‚˜ ๋ถ€๋ชจ์ธ์ง€๋ฅผ ํ™•์ธ ํ•ด๋ณผํ…Œ๊ณ  operator A()๋ฅผ ์ฐพ์•„ ๋ณผ์ง€๋„ ๋ชจ๋ฅธ๋‹ค.
๋งŒ์•ฝ ์ด ๋‘๊ฐœ๊ฐ€ ๋งŒ์กฑํ•˜๋Š” B๋ผ๋ฉด ์• ๋งค๋ชจํ˜ธ์„ฑ์˜ ๊ฒฝ์šฐ์ด๋‹ค. (์ด๋Ÿฐ ๊ฒฝ์šฐ๋Š” ๋งŒ๋“ค๋ฉด ์•ˆ๋ ๊บผ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.)

{{|
void f(int);
void f(char);

...

double d=6.02;
f(d)
|}}
๊ฐ€์žฅ ์‰ฝ๊ฒŒ ์ ‘ํ•  ์ˆ˜ ์žˆ๋Š” ์• ๋งค๋ชจํ˜ธํ•œ ๊ฒฝ์šฐ์ด๋‹ค.
์ด ๊ฒฝ์šฐ๋Š” static_cast<TYPE>๋ฅผ ํ†ตํ•ด ์‰ฝ๊ฒŒ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜๋‹ค.

{{|
class Base1
{
public:
int doIt();
}
class Base2
{
public:
int doIt();
}
class Derived : public Base1, public Base2
{
}

...

Derived d;
d.doIt();
|}}
๋Œ€ํ‘œ์ ์ธ ๋‹ค์ค‘์ƒ์†์˜ ์• ๋งค๋ชจํ˜ธ์„ฑ์ด๋‹ค.
์ด๊ฒƒ ๋˜ํ•œ ์ ‘๊ทผ๋ฒ”์œ„๋ฅผ ์„ค์ •ํ•ด ์คŒ์œผ๋กœ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜๋‹ค. (d.Base1::doIt()๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ)

์ด์™€ ๊ฐ™์€ ์˜ˆ์—์„œ ์•Œ์ˆ˜ ์žˆ๋“ฏ์ด C++์€ ์• ๋งค๋ชจํ˜ธ์„ฑ์„ ํ•˜๋‚˜์˜ ์„ฑ์งˆ๋กœ ๋ฐ›์•„ ๋“ค์˜€๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.
๊ทธ๋ž˜์„œ ๋Œ€๋ถ€๋ถ„์˜ ์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ์— ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์ด ์žˆ๋‹ค.

4.10. ํ•ญ๋ชฉ 27. ์˜๋„ํ•˜์ง€ ์•Š์€ ๋‚ด๋ถ€ ์ƒ์„ฑ ๋ฉค๋ฒ„ ํ•จ์ˆ˜์˜ ์ด์šฉ์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ง‰๋Š”๋‹ค.

์œ„์˜ ํ•ญ๋ชฉ์—์„œ ๋ณด๋“ฏ์ด C++์€ ์• ๋งค๋ชจํ˜ธ์„ฑ์„ ์ง€๋‹ˆ๊ณ  ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ ์ฝ”๋”ฉ์ƒ์˜ ์—๋Ÿฌ ์œ„ํ—˜์„ฑ์„ ๋‚ฎ์ถ”๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ตœ๋Œ€ํ•œ ๋ช…์‹œ์ ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์•ˆ์„ ๋„ฃ์œผ๋ฉด ์ข‹๋‹ค.

์˜ˆ๋กœ ์น˜ํ™˜์—ฐ์‚ฐ์ž๋ฅผ ์„ค๋ช…ํ•œ๋‹ค.
๋งŒ์•ฝ C++์˜ ํด๋ž˜์Šค๋กœ C ์–ธ์–ด์˜ ๋ฐฐ์—ด๊ณผ ์œ ์‚ฌํ•œ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ ์ž ํ•œ๋‹ค๋ฉด
C ์–ธ์–ด์˜ ๋ฐฐ์—ด๊ณผ ์œ ์‚ฌํ•œ ์„ฑ์งˆ์„ ์ง€๋…€์•ผ ํ•œ๋‹ค.
C ์–ธ์–ด์—์„œ ๋ฐฐ์—ด์˜ ์น˜ํ™˜์€ ๋ถˆ๋ฒ•์ด๋‹ค.
๊ทธ๋Ÿฌ๋ฏ€๋กœ C++์˜ ๋ฐฐ์—ดํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ๋„ ์น˜ํ™˜์—ฐ์‚ฐ์ž๋ฅผ ์ฝ”๋”ฉ์ƒ์˜ ๋ถˆ๋ฒ•์œผ๋กœ ๋งŒ๋“ค๋ฉด ์ฐจํ›„ ์• ๋งค๋ชจํ˜ธํ•œ์ ์ด ์—†์–ด์ง„๋‹ค.
C++์–ธ์–ด ํด๋ž˜์Šค ๊ธฐ๋ณธ ์น˜ํ™˜ ์—ฐ์‚ฐ์ž๋ฅผ ๋ฉค๋ฒ„์˜ ๋ณต์‚ฌ๋กœ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ
private์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๋ฉด ์ ์ ˆํ•˜๊ฒŒ ๋Œ€์ฒ˜ํ•œ ๊ฒฝ์šฐ์ด๋‹ค.

4.11. ํ•ญ๋ชฉ 28. ์ „์—ญ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๋ถ„ํ• ํ•œ๋‹ค.

C++์— ๋“ค์–ด์˜ค๋ฉด์„œ ์‚ฌ์šฉ๋œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ํ›Œ๋ฅญํ•œ ๋ชจ๋“ˆ๊ด€๋ฆฌ๋ฐฉ๋ฒ•์ด๋‹ค.
์•ฝ๊ฐ„์˜ ์ถ”๊ฐ€์ฝ”๋”ฉ์œผ๋กœ ๋งค์šฐ ์‰ฝ๊ฒŒ ์• ๋งค๋ชจํ˜ธ์„ฑ์„ ์ œ๊ฑฐํ•œ๋‹ค.

5. ํด๋ž˜์Šค์™€ ํ•จ์ˆ˜ : ๊ตฌํ˜„

5.1. ํ•ญ๋ชฉ 29. ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ "ํ•ธ๋“ค"์„ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•ด๋ผ.

๋‚ด๋ถ€ ์ž์›์— ๋Œ€ํ•œ ์ˆ˜์ •/์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ์ข‹์ง€ ๋ชปํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค.

๋งŒ์•ฝ ์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ
{{|
class String
{
...

public:
operator char *() const;
private:
char *data;
}

...

String B("Hello World");
char *str = B;
strcpy(str, "Hi Mom");
|}}
String B๋Š” ์ž์›์— ๋Œ€ํ•œ ํ•ธ๋“ค์„ ๋„˜๊ฒจ์ฃผ๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ์˜ ์œ ์ถœ์ด ๋ถˆ๊ฐ€ํ”ผํ•˜๋‹ค.

C++ ํ‘œ์ค€์˜ String์€ ๋ฐ˜ํ™˜๊ฐ’์„ constํ˜•์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” c_str๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ํ”ผํ•˜๊ณ  ์žˆ๋‹ค.
{{|
class String
{
...

public:
operator const char*() const;
}
|}}
์ด์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ถฉ๋ถ„ํžˆ ์œ„ํ—˜์„ ํ”ผํ•ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.

{{|
String someFamousAuthor()
{
return "E.H.Gombrich"; // the story of art์˜ ์ €์ž
}

...

const char *pc = someFamousAuthor();
cout << pc;
|}}
์ด์™€ ๊ฐ™์ด ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ ์ž„์‹œ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋˜๋ฉด์„œ ํฌ์ธํ„ฐ๋ฅผ ๋„˜๊ฒจ์ฃผ๊ณ  ์‚ญ์ œ๋œ๋‹ค.
๊ทธ๋ ‡๊ฒŒ ๋˜๋ฏ€๋กœ ์žƒ์–ด๋ฒ„๋ฆฐ ํ•ธ๋“ค(dangle handle)๋งŒ ๋‚จ๊ฒŒ ๋œ๋‹ค.

์ปดํŒŒ์ผ์ด ๋œ๋‹ค๋Š” ์ ์—์„œ ์• ๋งค๋ชจํ˜ธ์„ฑ๋ผ๊ณ  ํ• ์ˆ˜ ์žˆ์œผ๋‚˜ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ๋น„์šฉ์ด ๋งŽ์ด ๋“ ๋‹ค.
(์น˜ํ™˜์—ฐ์‚ฐ์ž์—์„œ const char*ํ˜•ํƒœ์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ๋„˜๊ฒจ์ค„๋•Œ ํ•ธ๋“ค์— ๋Œ€ํ•œ ์ž์›์„ ํ•˜๋‚˜ ๋” ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•˜๋ฉด ๊ฐ€๋Šฅ์€ ํ•˜๋‹ค.)

์‚ฌ์šฉ๋  ์„ฑ์งˆ์— ๋”ฐ๋ผ์„œ ํƒ€ํ˜‘;์„ ํ•˜์ž.

5.2. ํ•ญ๋ชฉ 30. ์ ‘๊ทผํ•˜๊ธฐ ์–ด๋ ค์šด ๋ฉค๋ฒ„์— ๋Œ€ํ•œ ๋น„์ƒ์ˆ˜ ํฌ์ธํ„ฐ๋‚˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜ ์‚ฌ์šฉ์„ ํ”ผํ•˜๋ผ.

๊ทผ๋ณธ์ ์ธ C++ ํด๋ž˜์Šค์˜ ์กด์žฌ์˜ ์ด์œ ์ด๋‹ค.
ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„๋Š” ์ด๋ฏธ ์ ‘๊ทผ์ž์˜ ๋œป์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
์ด ๋•Œ, ๋‚ด์šฉ์ด privateํ˜•๊ณผ ๊ฐ™์ด ๋‚ด๋ถ€์‚ฌ์šฉ๋งŒ ํ—ˆ๋ฝํ•  ๊ฒฝ์šฐ ์ด ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ˜•์‹์ด ๋‚˜์˜ค๋ฉด ์•ˆ๋œ๋‹ค.
(Stringํ˜•๊ณผ ๊ฐ™์ด C ์–ธ์–ด์˜ ํŠน์„ฑ๊ณผ ๋ฐ˜๋“œ์‹œ ํ˜ธํ™˜๋˜๊ฒŒ ํ•ด์•ผํ•  ๊ฒฝ์šฐ ์กฐ๊ธˆ์˜ ์˜ˆ์™ธ๋ผ๊ณ  ์ƒ๊ฐํ•ด๋„ ์ข‹์„๋“ฏ ํ•˜๋‹ค;;)

5.3. ํ•ญ๋ชฉ 31. ์ง€์—ญ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๋‚˜ ํ•จ์ˆ˜ ๋‚ด์—์„œ new๋ฅผ ์ด์šฉํ•ด ์ดˆ๊ธฐํ™”๋œ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฐธ์กฐ๋ฅผ ๋ฆฌํ„ดํ•˜์ง€ ๋ง๋ผ.

์ด๋ฒˆ ํ•ญ๋ชฉ์€ ์•ž์—์„œ ๋ช‡๋ฒˆ ์–ธ๊ธ‰ ๋˜์—ˆ๋˜๋“ฏ ํ•œ๋ฐ
{{|
class Rational
{
...

public:
friend const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational result(lhs.n*rhs.n, lhs.d,lhs.d);
return result;
}
private:
int n,d; // ๋ถ„๋ชจ์™€ ๋ถ„์ž๊ฐ’
}
|}}
์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ ์ง€์—ญ ๊ฐ์ฒด result๋Š” ํ•จ์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด์„œ ์‚ญ์ œ๋œ๋‹ค.

{{|
class Rational
{
...

public:
friend const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational *result = new Rational(lhs.n*rhs.n, lhs.d,lhs.d);
return *result;
}
private:
int n,d; // ๋ถ„๋ชจ์™€ ๋ถ„์ž๊ฐ’
}
|}}
๋งŒ์•ฝ ์ด์™€ ๊ฐ™์„ ๊ฒฝ์šฐ ํž™์˜์—ญ์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ•จ์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋”๋ผ๋„ ์‚ญ์ œ๊ฐ€ ๋˜์ง€ ์•Š์ง€๋งŒ
์ค‘๋ณต๋œ operator *์˜ ์‚ฌ์šฉ์‹œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ถœ์ด ๋ถˆ๊ฐ€ํ”ผํ•˜๋‹ค.

์ด ๋ฌธ์ œ์—์„œ๋Š” ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์•„๋‹Œ ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•จ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์œผ๋‚˜ ๋„ˆ๋ฌด ํฐ ๋น„์šฉ์ด ๋“ ๋‹ค.

  • ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์„ ์•„์‹œ๋Š” ๋ถ„์€ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”;;

5.4. ํ•ญ๋ชฉ 32. ๋ณ€์ˆ˜ ์ •์˜๋Š” ๊ฐ€๋Šฅํ•œ ๋’ค๋กœ ๋Šฆ์ถฐ๋ผ.

C ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ•จ์ˆ˜์˜ ์ฒซ๋จธ๋ฆฌ์— ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ  ์‹œ์ž‘ํ•˜์˜€๋‹ค.
์•„๋งˆ ์ดˆ๊ธฐ์˜ C ์–ธ์–ด์—์„œ ๋ณ€์ˆ˜์˜ ์ •์˜๊ฐ€ ์ฒซ๋จธ๋ฆฌ์— ์žˆ์–ด์•ผ ํ•จ๋„ ์žˆ์„ํ…Œ๊ณ  ๋ณ€์ˆ˜๋ฅผ ์‰ฝ๊ฒŒ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋„ ์‚ฌ์šฉ๋œ ๋ฐฉ๋ฒ•์ด๋‹ค.
์ด๋ฒˆ ๋‚ด์šฉ์€ ์ œ๋ชฉ๋Œ€๋กœ ๋ณ€์ˆ˜์˜ ์ •์˜๋ฅผ ๊ฐ€๋Šฅํ•œ ๋Šฆ์ถฐ์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์„ ์—†์• ๊ธฐ ์œ„ํ•จ์ด๋‹ค.

{{|
string encryptedPassword(const string &password)
{
string encrypted;
if(password.length() < MINIMUM_PASS_LENGTH)
throw logic_error("password is too short");
encrypted = password;
encrypt(encrypted);
return encrypted;
}
|}}
์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ ์˜ˆ์™ธ๋กœ ๋„˜์–ด๊ฐ€๊ฒŒ ๋  ๊ฒฝ์šฐ string encrypted; ์ฝ”๋“œ๋Š” ์“ธ๋ชจ๊ฐ€ ์—†๋‹ค.

{{|
string encryptedPassword(const string &password)
{
if(password.length() < MINIMUM_PASS_LENGTH)
throw logic_error("password is too short");

string encrypted(password);

encrypt(encrypted);
return encrypted;
}
|}}
์ด๋ ‡๊ฒŒ ๊ณ ์นจ์ด ํ˜„๋ช…ํ•˜๋‹ค.

  • ์š”์ฆ˜ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋Œ€์ถฉ ์ด์ •๋„๋Š” ์•Œ์•„์„œ ํ•ด์ฃผ์ง€ ์•Š๋‚˜์š”?;;

5.5. ํ•ญ๋ชฉ 33. ์ธ๋ผ์ธ์„ ์„ ๋ณ„์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ผ.

์ธ๋ผ์ธ์€ ๋งคํฌ๋กœ๋ณด๋‹ค ๋›ฐ์–ด๋‚˜๊ณ  ์‹คํ–‰์†๋„๋ฅผ ์ฆ๊ฐ€ ์‹œํ‚ฌ์ˆ˜๋„ ์žˆ์œผ๋‚˜ ๋•Œ์— ๋”ฐ๋ผ ์ถ”๊ฐ€์ ์ธ ์šฉ๋Ÿ‰์„ ์ƒ์„ฑ ์‹œํ‚ฌ์ˆ˜๋„ ์žˆ๋‹ค.
{{|
// "example.h" file
inline void f() { ... }

// "source1.cpp" file
#include "example.h"

// "source2.cpp" file
#include "example.h"
|}}
์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ ์ธ๋ผ์ธํ•จ์ˆ˜ f๋ฅผ source1.cpp์™€ source2.cpp์—์„œ ๊ฐ๊ฐ ์ƒ์„ฑ์‹œํ‚ฌ์ˆ˜๋„ ์žˆ๋‹ค.
์ด๊ฒƒ ๋ง๊ณ ๋„ ์ธ๋ผ์ธ ํ•จ์ˆ˜์˜ ํ•จ์ˆ˜ํฌ์ธํ„ฐ๋ฅผ ์ทจํ•  ๋•Œ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋”ฐ๋ผ ํŒŒ์ผ๋งˆ๋‹ค ์ •์  ๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑ์‹œํ‚ฌ์ˆ˜๋„ ์žˆ๋‹ค.
์ด๋ ‡๊ฒŒ ์ถ”๊ฐ€์ ์ธ ์šฉ๋Ÿ‰์ด ๋Š˜์–ด๋‚˜๋Š” ๊ฒฝ์šฐ ์™ธ์—๋„ ์บ์‹œ์˜ ์ ์ค‘๋ฅ ์„ ๊ฐ์†Œ์‹œ์ผœ ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์ด ๊ฐ์†Œํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

80-20 ํŒŒ๋ ˆํ† ์˜ ๋ถ„์„์— ๋”ฐ๋ผ ์ค‘์š”ํ•œ ์ฝ”๋“œ๋Š” ์•ฝ 20%๊ฐ€ ์ฐจ์ง€ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ•˜๊ณ  ์ค‘์š”ํ•œ ๋ถ€๋ถ„์—๋งŒ ์ธ๋ผ์ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์ž.

  • ์ƒ์„ฑ์ž์™€ ์†Œ๋ฉธ์ž๋Š” ์ธ๋ผ์ธ์œผ๋กœ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค. ์ด๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ตฌํ˜„์ž๊ฐ€ ๋•Œ์— ๋”ฐ๋ผ ์ƒ์„ฑ์ž์™€ ์†Œ๋ฉธ์ž์— ๋ณด์ด์ง€์•Š๋Š” ์ฝ”๋“œ๋ถ€๋ถ„์„ ํฌํ•จํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

5.6. ํ•ญ๋ชฉ 34. ํŒŒ์ผ๊ฐ„์˜ ์ปดํŒŒ์ผ ์˜์กด์„ฑ(dependency)์„ ์ตœ์†Œํ™”ํ•˜๋ผ.

ํŒŒ์ผ ํ•œ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•˜๊ณ  ๋‹ค์‹œ ์ปดํŒŒ์ผ์„ ์‹œ๋„ ํ–ˆ์„๋•Œ ๋ชจ๋“  ํŒŒ์ผ์„ ๋‹ค์‹œ ์ปดํŒŒ์ผํ•˜๊ณ  ๋งํฌํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ๊ฒฝํ—˜์„ ํ•œ๋ฒˆ์ฏค์€ ํ•ด๋ณด์•˜์œผ๋ฆฌ๋ผ ์ƒ๊ฐํ•œ๋‹ค.
์ด์™€ ๊ฐ™์ด ํŒŒ์ผ๊ฐ„์˜ ์˜์กด์„ฑ์œผ๋กœ ์ธํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ์ปดํŒŒ์ผ ์‹œ๊ฐ„์„ ์žก์•„๋จน๋Š”๊ฒƒ์€ ์‹œ๊ฐ„๋‚ญ๋น„์ด๊ณ  ์‚ฌ๋žŒ์— ๋”ฐ๋ผ ๋งค์šฐ ์งœ์ฆ๋‚˜๋Š” ์ผ์ด๋‹ค.
์ด๋ฒˆ ํ•ญ๋ชฉ์€ ๋ช‡๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํŒŒ์ผ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์‹œํ•œ๋‹ค.

์šฐ์„  ํด๋ž˜์Šค์˜ ์ „๋ฐฉ ์ฐธ์กฐ๋ฅผ ์„ค๋ช…ํ•œ๋‹ค.
์ „๋ฐฉ ์ฐธ์กฐ๋ฅผ ํ•จ์œผ๋กœ ํ—ค๋”๋ถ€๋ถ„์—์„œ๋Š” ์™ธ๋ถ€ ํด๋ž˜์Šค์˜ ๋‚ด์šฉ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ ๋” ์ด์ƒ์˜ ๋ฌด์˜๋ฏธํ•œ ์ปดํŒŒ์ผ์˜ ์—ฐ๊ฒฐ๊ณ ๋ฆฌ๋ฅผ ๋Š์„์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ƒํ™ฉ์— ๋”ฐ๋ผ์„œ๋Š” ๋ฐ˜๋“œ์‹œ ํด๋ž˜์Šค์˜ ๋‚ด์šฉ์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๊ณ  ๊ทธ๋Ÿด๋•Œ๋Š” ์ „๋ฐฉ ์ฐธ์กฐ์˜ ์˜๋ฏธ๋Š” ์•ฝํ•ด์ง„๋‹ค.

์ด๋Ÿด๋• Handleํด๋ž˜์Šค์™€ ํ”„๋กœํ† ์ฝœ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
Handleํด๋ž˜์Šค๋Š” ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉ๋  ๋‚ด์šฉ์˜ ๋ถ€๋ถ„์„ ๋”ฐ๋กœ ๋–ผ์–ด Handleํด๋ž˜์Šค๋กœ ๋งŒ๋“ฌ์œผ๋กœ ์ตœ์†Œํ•œ์˜ ๋‚ด์šฉ์„ ํ—ค๋”์— ํฌํ•จ์‹œํ‚จ๋‹ค.
ํ”„๋กœํ† ์ฝœ ํด๋ž˜์Šค๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ถ”์ƒํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๋งŒ๋“ค์–ด ํ—ค๋”์— ํฌํ•จ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํŒŒ์ผ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์•ฝํ™”์‹œํ‚จ๋‹ค.

6. ์ธ์Šคํ„ด์Šค์™€ ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„

6.1. ํ•ญ๋ชฉ 35. public ๊ณ„์Šน์ด "isa"๋ฅผ ๋ชจ๋ธ๋งํ•˜๋„๋ก ํ•˜๋ผ.

{{|
class Person
{
...
}
class Student : public Person
{
...
}
|}}
์ด ๊ด€๊ณ„๋Š” public ๊ณ„์Šน์ธ "isa"๊ด€๊ณ„์ด๋‹ค.
ํ•˜์ง€๋งŒ Person isa Student์ด์ง€ Student isa Person์ด ์•„๋‹˜์„ ์ฃผ์˜ํ•ด์•ผํ•œ๋‹ค.

์ปดํ“จํ„ฐ๋Š” 0๊ณผ 1๋กœ ์ด๋ฃจ์–ด์ง„ ๊ณ ์ฒ ์ด๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์„ ๋ฐ”๋กœ ํ‘œํ˜„ํ•˜์ง€ ๋ชปํ•œ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ์ˆ˜ํ•™์„ ํฌํ•จํ•œ ๋‹ค๋ฅธ ๋ถ€๋ถ„๋“ค์—์„œ ์ตํžŒ ์ง๊ด€์ด ๋ฐ”๋กœ ์ ์šฉ๋˜์ง€ ๋ชปํ•จ์„ ์ธ์‹ํ•ด์•ผ ํ•œ๋‹ค.

6.2. ํ•ญ๋ชฉ 36. ์ธํ„ฐํŽ˜์ด์Šค ๊ณ„์Šน๊ณผ ๊ตฌํ˜„ ๊ณ„์Šน์˜ ์ฐจ์ด์ ์„ ์ดํ•ดํ•˜๋ผ.

{{|
class Shape
{
...

public:
virtual void draw() const;
}
class Rectangle : public Shape { ... };
class Ellipse : public Shape { ... };

...

Shape *ps1 = new Rectangle;
ps1->draw();
Shape *ps2 = new Ellipse;
ps2->draw();
|}}
ํด๋ž˜์Šค Shape์—์„œ๋Š” ๊ตฌํ˜„ํ•  ๋‚ด์šฉ์˜ ์„ค๊ณ„๋งŒ ์žˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค๋“ค์—์„œ ๋‚ด์šฉ์˜ ๊ตฌํ˜„์ด ์žˆ๋‹ค.

๋งŒ์•ฝ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค์—์„œ ๊ฐ€์ƒํ•จ์ˆ˜์˜ ๊ตฌํ˜„์ด ๋˜์–ด ์žˆ์ง€ ์•Š์„ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.
์ด๋Ÿด๋•Œ ๊ฐ€์ƒํ•จ์ˆ˜๋กœ ์„ค์ •๋œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๋ฉด ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค.
{{|
class Shape
{
...

public:
virtual void draw const = 0;

protected:
void defaultdraw() const;
}

class Rectangle : public Shape
{
...

public:
virtual void draw() const
{
defaultdraw();
}
}
|}}
์ด๋ ‡๊ฒŒ ๊ฐ€์ƒํ•จ์ˆ˜๋ฅผ ์ˆœ์ˆ˜๊ฐ€์ƒํ•จ์ˆ˜๋กœ ๋ฐ”๊พธ๊ณ  ๊ทธ์— ๋”ฐ๋ฅธ ๊ธฐ๋ณธํ–‰๋™์— ๋Œ€ํ•œ ์ •์˜๋ฅผ defaultํ•จ์ˆ˜๋กœ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด ๋‘๋Š”๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋‹ค.

6.3. ํ•ญ๋ชฉ 37. ๊ณ„์Šน๋œ ๋น„๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

๊ฐ€์ƒํ•จ์ˆ˜์™€ ๋น„๊ฐ€์ƒํ•จ์ˆ˜์˜ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด๋‹ค.
์ƒ์†์ด ๋˜๋Š” ํ•จ์ˆ˜์— ๋Œ€ํ•˜์—ฌ ๊ฐ€์ƒํ•จ์ˆ˜๋กœ ์„ค์ •ํ•˜๋Š”๊ฒŒ ์˜ณ๊ณ  ์ƒ์†์ด ๋˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ƒ์†์ด ๋˜๋”๋ผ๋„ ๋‹ค์‹œ ๊ตฌํ˜„์ด ๋˜์ง€ ์•Š๋‹ค๋ฉด ๋น„๊ฐ€์ƒํ•จ์ˆ˜๋กœ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค.

6.4. ํ•ญ๋ชฉ 38. ๊ณ„์Šน๋œ ๋ถ€์žฌ ์ธ์ž๊ฐ’์„ ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

{{|
enum ShapeColor { RED, GREEN, BLUE };

class Shape
{
...

public:
virtual void draw(ShapeColor = RED) const;
}
class Rectangle : public Shape
{
...
public:
virtual void draw(ShapeColor = BLUE) const;
};

...

Shape *pr = new Rectangle;
pr->draw();
|}}
์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ pr์ด ํŒŒ๋ž€์ƒ‰ ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆด๊ฒƒ์ด๋ผ ์˜ˆ์ƒ์€ ํ•˜์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค.
pr์€ Shapeํ˜•์˜ ์ •์  ํฌ์ธํ„ฐ๋กœ ๋””ํดํŠธ์ธ์ž์™€๋Š” ์ •์ ์œผ๋กœ ๊ฒฐํ•ฉํ•œ๋‹ค.
๊ฒฐ๊ตญ ๋นจ๊ฐ„์ƒ‰ ์‚ฌ๊ฐํ˜•์ด ๊ทธ๋ ค์ง„๋‹ค.

์ด๋Š” ์„ฑ๋Šฅ์ƒ์˜ ์ด์œ ์ธ๋ฐ ๋””ํดํŠธ์ธ์ž์™€ ๋™์ ์œผ๋กœ ๊ฒฐํ•ฉ์‹œ ๋ณต์žกํ•˜๊ณ  ๋А๋ฆฌ๊ฒŒ ์ž‘๋™ํ•œ๋‹ค.
๋Œ€์‹  ์กฐ๊ธˆ ๋” ๋น ๋ฅด๊ฒŒ ์‹คํ–‰์ด ๋œ๋‹ค.

6.5. ํ•ญ๋ชฉ 39. ๊ณ„์ธต๋„์˜ ์•„๋ž˜์ชฝ ํด๋ž˜์Šค๋ฅผ ๋‹ค์šด์บ์ŠคํŠธ(downcast)ํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

{{|
class Person { ... };
class Student : public Person { ... };

...

Student *s = new Person;
|}}
์ด๊ฒƒ์€ ์˜ณ์ง€ ์•Š๋‹ค. ๊ผญ 100์›์งœ๋ฆฌ ๋™์ „๋งŒ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ €๊ธˆํ†ต์— 500์›์งœ๋ฆฌ ๋™์ „์„ ์šฐ๊ฒจ ๋„ฃ๋Š”๊ฒƒ๊ณผ ๊ฐ™๋‹ค.
๊ทธ๋Ÿฌ๋ฏ€๋กœ s๋ฅผ ํ†ตํ•ด Student๋งŒ์˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ์‹œ ์•Œ์ˆ˜ ์—†๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ผ ๊ฒƒ์ด๋‹ค.

๋˜๋„๋ก์ด๋ฉด ์ด๋Ÿฐ ๊ฒฝ์šฐ๋Š” ๊ฐ€์ƒํ•จ์ˆ˜์™€ ํด๋ž˜์Šค์˜ ๊ณ„์ธต๊ตฌ์กฐ๋ฅผ ํ†ตํ•œ ์ธํ„ฐํŽ˜์ด์Šค์˜ ํ™œ์šฉ์œผ๋กœ ํ•ด๊ฒฐํ•œ๋‹ค.
ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ’€๋ฆฌ์ง€ ์•Š์„ ๊ฒฝ์šฐ dynamic_cast์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฏธ๋ฆฌ ํƒ€์ž…์„ ์ฒดํฌํ•œํ›„ ์‹คํ–‰์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋„๋ก ํ•˜์ž.

6.6. ํ•ญ๋ชฉ 40. ๋ ˆ์ด์–ด๋ง(layering)์„ ํ†ตํ•ด "๊ฐ€์ง€๊ณ  ์žˆ๋Š”" ๊ฒƒ๊ณผ "์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋œ" ๊ฒƒ์„ ๋ชจ๋ธ๋งํ•˜๋„๋ก ํ•˜์ž.

Composition์œผ๋กœ๋„ ๋ถˆ๋ฆฌ๋Š” "has-a" ๊ด€๊ณ„์˜ ์ด์•ผ๊ธฐ ์ด๋‹ค.

๋งŒ์•ฝ STL์˜ ํฌํ•จ๋œ set์ด์™ธ์— ์ž์‹ ๋งŒ์˜ Set์„ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•˜๋Š” ์˜ˆ์ œ๊ฐ€ ์žˆ๋‹ค.
{{|
template<class T> class Set: public list<T> { ... };
|}}
์ด๊ฒƒ์€ ์˜ณ๋‹ค๊ณ  ๋ณด์ด๋‚˜ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค.
์™œ๋ƒํ•˜๋ฉด Derived๊ฐ€ Base์ด๋ฉด (isa), Base๊ฐ€ ์ฐธ์ผ๋•Œ ํ•ญ์ƒ Derived๋„ ์ฐธ์ด ๋œ๋‹ค.
Set์€ ์ค‘๋ณต๋œ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ํ•œ๋ฒˆ๋งŒ ์ž…๋ ฅ์„ ๋ฐ›๋Š” ์ž๋ฃŒํ˜•์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ "isa" ๊ด€๊ณ„๋กœ ๋‚˜ํƒ€๋‚ผ๋•Œ ์˜ณ์ง€ ๋ชปํ•˜๊ฒŒ ๋œ๋‹ค.

{{|
template<class T> class Set
{
...

public:
void insert(const T &ํ•ญ๋ชฉ);
private:
list<T> rep;
}

...

template<class T> void Set<T>::insert(const T& ํ•ญ๋ชฉ);
{
// ์ค‘๋ณต๋œ ๋‚ด์šฉ์ด ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ›„ ์ถ”๊ฐ€
}
|}}
์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด ํ•ด๊ฒฐ์ด ๋œ๋‹ค.

"isa" ๊ด€๊ณ„์™€ "has-a"๊ด€๊ณ„์ค‘ ์–ด๋А๊ฒƒ์ธ์ง€ ์ƒ๊ฐํ•˜๊ณ  ๊ตฌํ˜„ํ•˜์ž.

6.7. ํ•ญ๋ชฉ 41. ๊ณ„์Šน๊ณผ ํ…œํ”Œ๋ฆฟ๊ณผ์˜ ์ฐจ์ด์ ์„ ์ดํ•ดํ•œ๋‹ค.

ํ…œํ”Œ๋ฆฟ์€ ๊ฐ์ฒด์˜ ํƒ€์ž…์ด ํด๋ž˜์Šค์˜ ์ •์˜๋œ ํ•จ์ˆ˜๋“ค์˜ ๋™์ž‘ ์›๋ฆฌ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—, ํด๋ž˜์Šค์˜ ๋ชจ์Œ์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค.
๊ณ„์Šน์€ ๊ฐ์ฒด์˜ ํƒ€์ž…์ด ํด๋ž˜์Šค์— ์ •์˜๋œ ํ•จ์ˆ˜๋“ค์˜ ๋™์ž‘ ์›๋ฆฌ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ์—, ํด๋ž˜์Šค์˜ ๋ชจ์Œ์„ ์œ„ํ•ด ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค.

๋งŒ์•ฝ ์Šคํƒ์„ ํ…œํ”Œ๋ฆฟ์ด ์•„๋‹Œ ๊ณ„์Šน์„ ํ†ตํ•ด ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊ฒƒ์ธ๊ฐ€๋ฅผ ์ƒ๊ฐํ•ด ๋ณด๊ณ 
์ƒ๋ฌผ->๋™๋ฌผ->์ธ๊ฐ„->ํ•™์ƒ๋“ฑ์˜ ํ˜•์‹์„ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž.

ํ…œํ”Œ๋ฆฟ์ด ์•„๋‹Œ ๊ณ„์Šน์„ ํ†ตํ•œ ์Šคํƒ์˜ ๊ตฌํ˜„์ด๋ผ๋ฉด voidํ˜• ํฌ์ธํ„ฐ๋“ฑ์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์ž๋ฃŒํ˜•์„ ๋™์ ์œผ๋กœ ์ž…๋ ฅ๋ฐ›๋„๋ก ๋…ธ๋ ฅํ•  ๊ฒƒ์ด๋ฉฐ
๊ณ„์ธต๊ตฌ์กฐ๋ฅผ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๋ฌถ๊ณ ์ž ํ•œ๋‹ค๋ฉด ํ…œํ”Œ๋ฆฟํ˜•์— ๋”ฐ๋ผ if๋ฌธ์„ ๋Œ๋ฆฌ๋Š”๋“ฑ C, PASCAL์˜ ํ˜•์‹์„ ๋”ฐ๋ฅผ์ง€๋„ ๋ชจ๋ฅธ๋‹ค.

6.8. ํ•ญ๋ชฉ 42. private ๊ณ„์Šน์„ ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋ผ.

private ๊ณ„์Šน์€ layering๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•˜๋‹ค. public ๊ณ„์Šน๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ Derived isa Base์ด์ง€๋„ ์•Š๋‹ค.
๋‹จ์ง€ layering๊ณผ ์ฐจ์ด์ ์€ Baseํด๋ž˜์Šค์—์„œ protected๊ณผ private์˜ ์‚ฌ์šฉ์œ ๋ฌด์˜ ์ฐจ์ด์ด๋‹ค.
๋งŒ์•ฝ ๋งŒ๋“ค๊ณ ์ž ํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ protected๋‚˜ private๋ฉค๋ฒ„๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด layering๋งŒ์œผ๋กœ๋Š” ์ฒ˜๋ฆฌํ• ์ˆ˜๊ฐ€ ์—†๋‹ค.
์ด๋Ÿด๋•Œ private ๊ณ„์Šน์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

{{|
class GenericStack
{
...

public:
void push(const void *Object);
void *pop();
}
|}}
์ด๋ ‡๊ฒŒ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ํฌ์ธํ„ฐ์— ๋Œ€ํ•œ ์Šคํƒ์ด ์žˆ๋‹ค๊ณ  ํ• ๋•Œ. ์ด ํด๋ž˜์Šค๋งŒ์œผ๋กœ๋Š” ํƒ€์ž…์ด ์•ˆ์ •ํ•˜์ง€ ๋ชปํ•˜๋‹ค.

{{|
class GenericStack
{
protected:
... // ์ƒ์„ฑ์ž, ์†Œ๋ฉธ์ž ๋ฐ ์ƒ๋žต๋œ ๋‚ด์šฉ

void push(const void *Object);
void *pop();
}

class IntStack : private GenericStack
{
...

public:
void push(int *intPtr)
{
GenericStack::push(intPtr);
}
int *pop()
{
return static_cast<int*>(GenericStack::pop());
}
}

...

GenericStack gs; // ์—๋Ÿฌ : ์ƒ์„ฑ์ž๊ฐ€ protected์ด๋‹ค.
IntStack is; // Int ํฌ์ธํ„ฐํ˜•์— ๋Œ€ํ•œ ์•ˆ์ •ํ•œ ์Šคํƒ์ด๋‹ค.
|}}
ํƒ€์ž…์•ˆ์ •ํ•˜๊ณ  GenericStack๋งŒ์œผ๋กœ๋Š” ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋„๋ก ๋ง‰์•„๋†“์•˜๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ layering์ด ์“ฐ๊ณ  ์ด์™€ ๊ฐ™์ด ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋งŒ private ๊ณ„์Šน์„ ์“ฐ๋„๋ก ํ•˜์ž.

6.9. ํ•ญ๋ชฉ 43. ๋‹ค์ค‘ ๊ณ„์Šน์„ ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋ผ.

๋‹ค์ค‘ ๊ณ„์Šน์€ ์• ๋งค๋ชจํ˜ธํ•œ ๋ถ€๋ถ„์ด ๋งŽ๋‹ค.

{{|
class A { ... };
class B : public A { ... };
class C : public A { ... };
class D : public B, public C { ... };
|}}
์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ ๋งค์šฐ ์ค‘๋ณต์ ์ด๊ณ  ๋งค์šฐ ์œ„ํ—˜ํ•œ ์ฝ”๋“œ์ด๋‹ค.
ํด๋ž˜์Šค A๋ถ€๋ถ„์— ์žˆ๋Š” ๊ฐ€์ƒํ•จ์ˆ˜๋ฅผ B์™€ C์—์„œ ๊ตฌํ˜„ํ•˜์˜€๋‹ค๋ฉด ํด๋ž˜์Šค D์—์„œ ํ˜ธ์ถœ๋˜๋Š” ๊ฐ€์ƒํ•จ์ˆ˜๋Š” ๋ฌด์—‡์„ ๋œปํ•˜๋Š”์ง€ ์•Œ์ˆ˜ ์—†๋‹ค.
์ด๊ฒƒ์€ ์ตœ์•…์˜ ์„ค๊ณ„๋กœ ์ด๋Ÿฐ ๋ฐฉ๋ฒ•์€ ํ”ผํ•ด์•ผ ํ•œ๋‹ค.

์ตœ๋Œ€ํ•œ ์œ„์™€ ๊ฐ™์€ ๋‹ค์ด์•„๋ชฌ๋“œํ˜• ์ƒ์†์€ ํ”ผํ•˜์ž.
์ž๋ฐ”์—์„œ๋Š” ์ƒ์†๋ฐ›์„ ํด๋ž˜์Šค๋Š” ํ•˜๋‚˜๋งŒ ๋ฐ›์„์ˆ˜ ์žˆ๊ณ  ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

6.10. ํ•ญ๋ชฉ 44. ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋ฅผ ํ‘œํ˜„ํ•˜๋„๋ก ํ•˜๋ผ. ์ž์‹ ์ด ํ‘œํ˜„ํ•œ ๊ฒƒ์˜ ์˜๋ฏธ๋ฅผ ์ดํ•ดํ•˜๋„๋ก ํ•˜๋ผ.

์œ„์˜ ๋‚ด์šฉ์„ ์š”์•ฝํ•œ ๋‚ด์šฉ์ด๋‹ค.

7. ๋ฏธ๋ฌ˜ํ•œ ๋ถ€๋ถ„

7.1. ํ•ญ๋ชฉ 45. C++๊ฐ€ ์€๋ฐ€ํ•˜๊ฒŒ ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ํ˜ธ์ถœํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ

{{|
class Empty { };
|}}
๋งŒ์•ฝ ์ด๋ ‡๊ฒŒ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋ฉด

{{|
class Empty
{
public:
Empty();
Empty(const Empty& rhs);
~Empty();

Empty& operator=(const Empty& rhs);
Empty* operator();
const Empty* operator&() const;
}
|}}
์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.

7.2. ํ•ญ๋ชฉ 46. ์‹คํ–‰ ์‹œ๊ฐ„ ์—๋Ÿฌ๋ณด๋‹ค๋Š” ์ปดํŒŒ์ผ ์‹œ๊ฐ„๊ณผ ๋งํฌ ์‹œ๊ฐ„ ์—๋Ÿฌ๊ฐ€ ์ข‹๋‹ค.

C++์€ ์ปดํŒŒ์ผ๋˜๋Š” ์–ธ์–ด๋กœ ์‹คํ–‰์‹œ๊ฐ„์—๋Š” ์—๋Ÿฌ๋ฅผ ํƒ์ง€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
๊ทธ ๋Œ€์‹  ๋น ๋ฅธ ์ˆ˜ํ–‰์‹œ๊ฐ„์˜ ์ด์ต์ด ์žˆ๊ณ  ์‹คํ–‰ ์‹œ๊ฐ„์˜ ์—๋Ÿฌ๋ฅผ ์˜ˆ๋ฐฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ปดํŒŒ์ผ ์‹œ๊ฐ„๊ณผ ๋งํฌ ์‹œ๊ฐ„์— ์œ„ํ—˜์„ ์ œ๊ฑฐํ•˜๋„๋ก ํ•ด์•ผ ๋œ๋‹ค.

๋‚ ์งœ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•œ ํด๋ž˜์Šค ์ด๋‹ค.
{{|
class Date
{
...

public:

Date(int day, int month, int year);
}
|}}
์—ฌ๊ธฐ์„œ Month์˜ ๊ฐ’์˜ ์œ ํšจ์„ฑ ์ฒดํฌ๋ฅผ ์œ„ํ•ด์„œ ๊ณ ์ณ๋ณด์ž.
{{|
class Date
{
...

public:

Date(int day, const Month& month, int year);
}

class Month
{
public:
static const Month Jan() { return 1; };
static const Month Feb() { return 2; };
...
static const Month Dec() { return 12; };
private:
Month(int number) : monthNumber(number) { }
Month(const Month& rhs);
const int monthNumber;
};

...

Date d(30,Month::Sep(),2003);
|}}
์ด์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ Month๋Š” ์‹คํ–‰์‹œ๊ฐ„์— ๊ฒ€์‚ฌ๋ฅผ ํ•ด์•ผ ํ•  ๋‚ด์šฉ์„ ์ปดํŒŒ์ผ ์‹œ๊ฐ„์œผ๋กœ ์˜ฎ๊ธธ์ˆ˜ ์žˆ๋‹ค.

7.3. ํ•ญ๋ชฉ 47. ๋น„์ง€์—ญ ์ •์ (Non-local static) ๊ฐ์ฒด๋Š” ์‚ฌ์šฉ๋˜๊ธฐ ์ „์— ์ดˆ๊ธฐํ™”๋˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.

๋งŒ์•ฝ ํŒŒ์ผ์‹œ์Šคํ…œ์ด ์ดˆ๊ธฐํ™”๋œํ›„ ๋””๋ ‰ํ† ๋ฆฌ ์‹œ์Šคํ…œ์˜ ๋ถ€๋ถ„์œผ๋กœ ์ดˆ๊ธฐํ™” ๋˜์–ด์•ผ ํ•œ๋‹ค๋ฉด
๋ฐ˜๋“œ์‹œ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋„๋ก ํ•ด์•ผํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋น„์ง€์—ญ ๊ฐ์ฒด๋กœ ์„ ์–ธ์ด ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ดˆ๊ธฐํ™” ์ˆœ์„œ๋ฅผ ์ •ํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ํž˜๋“ค ๊ฒƒ์ด๋‹ค.
(๋น„์ง€์—ญ ๊ฐ์ฒด๋Š” ์ „์—ญ์ด๋‚˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์˜์—ญ์ด๊ฑฐ๋‚˜ ํด๋ž˜์Šค๋‚ด static, ํŒŒ์ผ ์˜์—ญ์˜ static์— ์ •์˜๋œ ๊ฒฝ์šฐ์ด๋‹ค.)

์ด๋Ÿด ๋•Œ๋Š”
{{|
FileSystem& theFileSystem()
{
static FileSystem tfs;
return tfs;
}

...

class Directory
{
...
public:
Directory()
{
// theFileSystem ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋””๋ ‰ํ† ๋ฆฌ ๋ถ€๋ถ„์„ ์ดˆ๊ธฐํ™” ์‹œํ‚จ๋‹ค.
}
}
|}}
์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ ๋ฐ˜๋“œ์‹œ Directoryํด๋ž˜์Šค๊ฐ€ ์ดˆ๊ธฐํ™” ๋˜๊ธฐ์ „์— FileSystem์„ ์ดˆ๊ธฐํ™” ์‹œํ‚ฌ์ˆ˜ ์žˆ๋‹ค.

7.4. ํ•ญ๋ชฉ 48. ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๊ฒฝ๊ณ (Warning)์— ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์—ฌ๋ผ.

C++ ์–ธ์–ด๋Š” ์œ ์—ฐํ•˜๋‹ค.
{{|
class B
{
public:
virtual void f() const;
}

class D
{
public:
virtual void f();
}
|}}
์ด์™€ ๊ฐ™์ด ์žฌ์ •์˜๋ฅผ ํ•˜์˜€์„ ๋•Œ, Error๊ฐ€ ์•„๋‹Œ Warning์„ ๋งŒ๋“ค์–ด ๋‚ผ์ˆ˜๋„ ์žˆ๋‹ค.

Error๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Warning์—๋„ ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ด์ž. ์ž ์žฌ์ ์ธ ๋ฌธ์ œ ์š”์†Œ๊ฐ€ ๋ ์ˆ˜๋„ ์žˆ๋‹ค.

7.5. ํ•ญ๋ชฉ 49. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž˜ ์•Œ์•„๋‘์ž.

ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์œ ์šฉํ•˜๋‹ค!

7.6. ํ•ญ๋ชฉ 50. C++์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋„“ํ˜€๋ผ.

๊ทธ๋ƒฅ ์ฝ์–ด ๋ณผ๊ฒƒ.


8. Thread

๊ทธ๋ƒฅ ๋ณด๋ฉด ์ˆ ์ˆ ์ˆ  ๋„˜์–ด ๊ฐ€๋Š”๋ฐ.. ์“ฐ๋ ค๋‹ˆ ๋ง‰๋ง‰ํ•˜๊ตฌ๋‚˜.. guts__

Effective C++ ๋‚ด์šฉ์„ ๋ณด๋ฉด์„œ ์ด๋ฏธ ํ•ญ๋ชฉ 21 ๊นŒ์ง€๋Š” ์ •๋ฆฌ๊ฐ€ ๋˜์–ด ์žˆ๋”๊ตฐ์š”.
๊ทธ๋ž˜์„œ ๊ทธ ์ดํ•˜ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด ์˜ฌ๋ฆฌ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. -- ๋‹ค๋ฅธํ•™๊ต์ปดํ“จํ„ฐ๊ณตํ•™๋ถ€
์ด๊ณณ์—๋Š” ํŠน๋ณ„ํžˆ ํ—ˆ๋ฝ์„ ํ•˜๊ฑฐ๋‚˜, ํ—ˆ๋ฝ์„ ๋ฐ›์„๋งŒํ•œ ์‚ฌ๋žŒ์ด ์—†์Šต๋‹ˆ๋‹ค. ์–ธ์ œ๋“  ํ™˜์˜์ž…๋‹ˆ๋‹ค :) --sun

์•ˆํ˜์ค€ํ˜•์ด ์ฝ์œผ๋ผ๊ณ  ์ถ”์ฒœํ•ด ์ค€ ์ฑ….. ์€ ์œ„ํ‚ค์— ๋ฉ‹์ง€๊ฒŒ๋„ ์ •๋ฆฌ๊ฐ€ ๋˜์–ด์žˆ๊ตฐ์š”. ์ „ ๋น…๋ฑ…์„ ๋‚˜๊ฐ€์ง€ ๋ชปํ•˜๋‹ˆ ํ˜ผ์ž์„œ๋ผ๋„ ์—ด์‹ฌํžˆ ํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค. - ๊ถŒ์˜๊ธฐ

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:10
Processing time 0.0453 sec