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