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