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.1684 sec