U E D R , A S I H C RSS

More EffectiveC++/Efficiency

1. Efficiency

1.1. Item 16:Remember the 80-20 rule.

  • Item 16:80-20 κ·œμΉ™μ„ 기얡해라.

DeleteMe ) ν•΄λ‹Ή 슀크립트의 뒷뢀뢄이 μ œλŒ€λ‘œ 이해가 μ•ˆκ°„λ‹€. λ‹Ήμ—°ν•œ λ‚΄μš©μ„ κΌ¬μ•„ 쓴것 같은데, μ°¨ν›„ μˆ˜μ • μ‹œλ„ ν•˜κ² μŒ --상λΌ

80-20 κ·œμΉ™ μ΄λž€? ν”„λ‘œκ·Έλž¨μ˜ 80%의 λ¦¬μ†ŒμŠ€κ°€ 20%의 μ½”λ“œμ—μ„œ 쓰여진닀.:μ‹€ν–‰ μ‹œκ°„μ˜ 80%κ°€ λŒ€λž΅ 20%의 μ½”λ“œλΌ μ†Œλͺ¨ν•œλ‹€;80%의 λ©”λͺ¨λ¦¬λŠ” μ–΄λ–€ 20%의 μ½”λ“œμ—μ„œ μ“΄λ‹€.;80%의 disk 접근은 20%의 μ½”λ“œμ—μ„œ 이루어진닀.:80%의 μ†Œν”„νŠΈμ›¨μ–΄ μœ μ§€μ˜ λ…Έλ ₯은(maintenance effort)λŠ” 20%의 μ½”λ“œμ— μŸμ•„ 뢀어진닀.

80-20 κ·œμΉ™μ€ μˆ˜λ§Žμ€ κΈ°κ³„μ—μ„œ, 운영체제(Operating System)μ—μ„œ, 그리고 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ μš©λœλ‹€. 80-20 κ·œμΉ™μ€ 단지 재λΈμžˆλŠ” ν‘œν˜„λ³΄λ‹€ 더 λ§Žμ€ 의λΈκ°€ μžˆλ‹€.;그것은 κ΄‘λ²”μœ„ν•˜κ³ , μ‹€μ§ˆμ μΈ κ°œλ…μ΄ ν•„μš”ν•œ μ‹œμŠ€ν…œμ˜ μ„±λŠ₯(λŠ₯λ₯ )에 κ°œμ„  λŒ€ν•œ κΈ°μ€μ μ„ μ œμ‹œν•œλ‹€.

80-20 κ·œμΉ™μ„ μƒκ°ν• λ•Œ 이 μˆ«μžμ— λ„ˆλ¬΄ 맀달릴 ν•„μš”λŠ” μ—†λ‹€. λ•Œλ‘œ μ‚¬λžŒλ“€μ€ 90-10이 λ μˆ˜λ„ μžˆλŠ”κ±°κ³ , μ‹€ν—˜μ μΈ 근거도 μ—­μ‹œλ‚˜ κ·Έλ ‡κ²Œ 될수 μžˆλŠ” 것이닀. μ •ν™•ν•œ μˆ«μžμ΄λ“ , μ€‘μš”ν•œ μ‚¬μ•ˆ,ν¬μΈνŠΈλŠ” λ°”λ‘œ 이것이닀.: λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄μ˜ μˆ˜ν–‰μ˜ λΆ€ν•˜λŠ” 거의 항상 μ†Œν”„νŠΈμ›¨μ–΄μ˜ μž‘μ€ λΆ€λΆ„μ—μ„œ κ²°μ •λ˜μ–΄ μ§„λ‹€λŠ” 점이닀.

ν”„λ‘œκ·Έλž˜λ¨Έμ˜ λ…Έλ ₯이 λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄μ˜ μ„±λŠ₯ κ°œμ„ μ— 촛점을 λ§žμΆ”κ²Œ λœλ‹€λ©΄ 80-20 κ·œμΉ™μ€ λ‹Ήμ‹ μ˜ μƒν™œμ„ κ°„νŽΈν•˜κ²Œ(μœ€νƒν•˜κ²Œ), ν˜Ήμ€ μ€λ” 볡작히(μ–΄λ ΅κ²Œ) λ§Œλ“€μ–΄ λ‚˜κ°ˆκ²ƒμ΄λ‹€. κ°„νŽΈν•˜κ²Œ(μœ€νƒν•˜κ²Œ) μͺ½μ„ μƒκ°ν•œλ‹€λ©΄, 80-20 κ·œμΉ™μ€ 당신이 μ„±λŠ₯에 λŒ€ν•˜μ—¬ μ†”μ§νžˆ μ–΄λŠ 정도 ν‰λ²”ν•œ μ½”λ“œμ˜ μž‘μ„±μ„ λŒ€λ‹€μˆ˜μ— μ‹œκ°„μ„ λ³΄λ‚Όμˆ˜ μžˆμŒμ„ 의λΈν•œλ‹€.μ™œλƒν•˜λ©΄ 당신이 μΌν•˜λŠ” μ‹œκ°„μ˜ 80%에 μž‘μ„±λœ 것은 μ‹œμŠ€ν…œμ˜ μ„±λŠ₯에 κ΄€ν•΄ νŠΉλ³„νžˆ ν•΄λΌ λΌμΉ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 의λΈμ΄κΈ° λ•Œλ¬Έμ΄λ‹€. μ €μ˜λΈλŠ” μ•„λ§ˆ λ§Žμ€ 뢀뢄이 당신을 μœ„ν•œ 말은 μ•„λ‹ˆμ§€λ§Œ, 그것은 λ‹Ήμ‹ μ˜ 슀트레슀 μ •λ„λΌ λ‹€μ†Œ μ„μ—¬μ„μˆ˜ μžˆλ‹€. 볡작히(μ–΄λ ΅κ²Œ)λΌ μƒκ°ν•΄ λ³Έλ‹€λ©΄ 80-20 κ·œμΉ™μ€ λ§Œμ•½ 당신이 μ„±λŠ₯λ¬Έμ œλΌ κ°€μ§€κ³  μžˆλ‹€λ©΄ λ‹Ήμ‹  μ•žμ— 놓여진 일은 ν—˜ν•˜λ‹€λŠ” κ±Έ 의λΈν•œλ‹€. μ™œλƒν•˜λ©΄, 당신은 였직 κ·Έ λ¬Έμ œλΌ μΌμœΌν‚€λŠ” μž‘μ€λŸ‰μ˜ μ½”λ“œλ“€μ„ μ œκ±°ν•΄μ•Ό ν•˜κ³ , μ„±λŠ₯을 λΉ„μ•½μ μœΌλ‘œ ν–₯μƒμ‹œν‚€λŠ” 방법을 μ°Ύμ•„μ•Ό ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. μ΄λ ‡κ²Œ 80-20 κ·œμΉ™μ€ λ‘κ°€μ§€μ˜ λ°˜λŒ€λ˜λŠ” λ‹€λ₯Έ κ΄€μ μ—μ„œμ˜ 접근이 주어진닀.:λŒ€λ‹€μˆ˜ μ‚¬λžŒλ“€μ€ κ·Έλ ‡κ²Œν•˜κ³ , μ˜μ€ 방법을 ν–‰ν•΄μ•Ό 할것이닀.

λ§Žμ€ μ‚¬λžŒλ“€μ΄ 병λͺ©ν˜„상(bottleneck)에 κ΄€ν•œ 해결책에 κ³ μ‹¬ν•œλ‹€. κ²½ν—˜μ— λ”°λ₯Έ 방법, 직관λ ₯, tarot μΉ΄λ“œμ΄μš©(μš΄μ— 맏기기) 그리고 Ouija(μ κ΄˜λΌ λ‚˜νƒ€λ‚΄λŠ” λ„νŒμ§€μ˜ μƒν‘œλͺ…, 즉 점보기) λ³΄λ“œλΌ μ‚¬μš© ν•˜κΈ°λ„ ν•˜κ³ , μ†Œλ¬Έμ΄λ‚˜ 잘λͺ», μ˜¬λ°”λ₯΄μ§€ μ•Šμ€ λ©”λͺ¨λ¦¬ ν• λ‹Ή, μΆ©λΆ„ν•˜μ§€ μ•Šμ€ μ΅œμ ν™”λΌ ν•œ 컴파일러, ν˜Ήμ€ 치λͺ…적인 μˆœν™˜ ꡬ문을 λ§Œλ“€μ–΄λ‚΄κΈ° μœ„ν•΄ μ–΄μ…ˆλΈ”λ¦¬ μ–Έμ–΄λΌ μ‚¬μš©ν•œ λŒλŒ€κ°€λ¦¬ λ©”λ‹ˆμ €λ“€μ˜ λ©”λ‹ˆμ €λ“€. μ΄λŸ¬ν•œ 사정듀은 일반적으둜 λ©Έμ‹œμ˜ λΉ„μ›ƒμŒμ„ λ™λ°˜ν•˜κ³ , κ·Έλ“€μ˜ μ˜ˆμ–Έμ€ μ†”μ§νžˆ 잘λͺ»λœ 것이닀.

(DeleteMe 이후 μ˜μ–΄ 해석이 λ„ˆλ¬΄ λͺ¨ν˜Έν•˜λ‹€. 사싀 λ‚΄μš©μ„ 잘 μ΄ν•΄λΌ λͺ»ν–ˆλ‹€. μ°¨ν›„ 고치자. 이 전도 λ§ˆμ°¬κ°€μ§€)

λŒ€λΆ€λΆ„ ν”„λ‘œκ·Έλž˜λ¨Έλ“€μ€ κ·Έλ“€μ˜ ν”„λ‘œκ·Έλž¨μ— κ΄€ν•œ νŠΉμ„±μ— κ΄€ν•˜μ—¬ λ©μ²­ν•œ 직관λ ₯을 가지고 μžˆλ‹€. μ™œλƒν•˜λ©΄ ν”„λ‘œκ·Έλž¨ μ„±λŠ₯의 νŠΉμ§•μ€ μ•„μ£Ό 직관적이지 λͺ»ν•˜λ‹€. 결과적으둜 남에 λˆˆμ—λŠ” 띄지 μ•Šκ³  λ§ν• μˆ˜ λ§Žμ€ λ…Έλ ₯이 μ„±λŠ₯ ν–₯상을 μœ„ν•΄ ν”„λ‘œκ·Έλž¨μ˜ κ΄€λ ¨λœ 뢀뢄에 μŸμ•„ λΆ€μ–΄ 진닀. 예λΌλ“€μ–΄μ„œ μ•„λ§ˆ, 계산을 μ΅œμ†Œν™” μ‹œν‚€λŠ” μ•Œκ³ λ¦¬μ¦˜κ³Ό 데이터 ꡬ쑰가 ν”„λ‘œκ·Έλž¨μ— 적용 λ˜λ‹€. κ·Έλ ‡μ§€λ§Œ λ§Œμ•½μ— μž…μΆœ(I/O-bound)λ ₯ λΆ€λΆ„ μ μš©λœλ‹€λ©΄ 저것은 ν—ˆμ‚¬κ°€ λœλ‹€. μ¦κ°€λ˜λŠ” I/O λΌμ΄λΈŒλŸ¬λ¦¬λŠ” μ•„λ§ˆ μ»΄νŒŒμΌλŸ¬μ— μ˜ν•˜μ—¬ 바뀐 κ·Έ μ½”λ“œμ— μ˜ν•΄ ꡐ체될것이닀. κ·Έλ ‡μ§€λ§Œ, ν”„λ‘œκ·Έλž¨μ΄ CPU-bound에 λŒ€ν•œ μ‚¬μš©μ΄λΌλ©΄ 또 이건 λ³„λ‘œ μ€‘μš”ν•œ 포인터(관점)이 λ˜μ§€ μ•ŠλŠ” 것이닀.

μ €λŸ¬ν•œ μƒν™©μ—μ„œ, λ§Œμ•½ λ‚΄κ°€ 느린 ν”Œκ·Έλž¨μ΄λ‚˜ λ„ˆλ¬΄ λ§Žμ€ ν”„λ‘œκ·Έλž¨μ„ λ§Œλ‚˜λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν•˜λŠ”κ°€? 80-20 κ·œμΉ™μ€ ν”„λ‘œκ·Έλž¨μ˜ 랜덀 κ΅¬μ—­μ˜ μ¦κ°€λŠ” λ•λŠ”λ° μ©μ’‹μ§€λŠ” μ•Šλ‹€λŠ” κ±Έ 의λΈν•œλ‹€. 사싀, ν”„λ‘œκ·Έλž¨μ€ μ„±λŠ₯ ν–₯상은 비직관적이닀. ν•˜μ§€λ§Œ λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ—μ„œ λ‹¨μˆœν•œ 랜덀 λΆ€λΆ„μ˜ 증가보닀 μ„±λŠ₯의 병λͺ© 지점을 μ°ΎλŠ” 생각에 λ…Έλ ₯을 κΈ°μšΈμ΄λŠ” 것이 더 쒋와 λ³΄μ΄μ§€λŠ” μ•Šμ€ 것이닀. 자 그럼 일해 λ³΄μ‹€κΉŒμš”?

일을 ν•  κ·Έ 뢀뢄은 μ‹€μ§ˆμ μœΌλ‘œ λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ˜ 20%둜, λ‹Ήμ‹ μ—κ²Œ κ³ λΌμ„ μ•ˆκ²¨μ£ΌλŠ” 뢀뢄이닀. 그리고 λ”μ°ν•œ 20%λΌ μ°ΎλŠ” 방법은 ν”„λ‘œκ·Έλž¨ ν”„λ‘œνŒŒμΌλŸ¬(profiler:λΆ„μ„μž)λΌ μ‚¬μš©ν•˜λŠ” 것이닀. κ·Έλ ‡μ§€λ§Œ μ–΄λ– ν•œ ν”„λ‘œνŒŒμΌλŸ¬(profiler:λΆ„μ„μž)도 λͺ»ν• μΌμ΄λ‹€. 당신은 κ°€μž₯ 관심 μžˆλŠ” 직접적인 해결책을 λ‚΄λ†“λŠ” 것을 μ›ν•œλ‹€.μ˜ˆλΌ λ“€μžλ©΄ λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ΄ 맀우 λŠλ¦¬λ‹€κ³  ν•˜μž, 당신은 ν”„λ‘œνŒŒμΌλŸ¬(profiler:λΆ„μ„μž)κ°€ ν”„λ‘œκ·Έλž¨μ˜ 각각 λ‹€λ₯Έ λΆ€λΆ„μ—μ„œ μ–Όλ§ˆλ‚˜ μ‹œκ°„μ΄ μ†ŒλΉ„λ˜λŠ”μ§€μ— κ΄€ν•΄μ„œ 말해μ„κ»„ μ›ν•œλ‹€. 당신이 λ§Œμ•½ κ·ΈλŸ¬ν•œ λŠ₯λ₯  κ΄€μ μœΌλ‘œ μ€‘μš”ν•œ ν–₯상을 이룰수 μžˆλŠ” 뢀뢄에 κ΄€ν•΄ 촛점을 λ§žμΆ”λŠ” λ°©λ²•λ§Œ μ•Œκ³  μžˆλ‹€λ©΄ λ˜ν•œ 전체 λΆ€λΆ„μ—μ„œ νš¨μœ¨μ„±μ„ μ¦λŒ€μ‹œν‚€λŠ” 뢀뢄을 λ§ν• μˆ˜μžˆμ„ 것이닀.

ν”„λ‘œνŒŒμΌλŸ¬(profiler:λΆ„μ„μž)λŠ” 각각의 ꡬ문이 λͺ‡λ²ˆμ΄λ‚˜ μ‹€ν–‰λ˜λŠ”κ°€ μ•„λ‹ˆλ©΄ 각각의 ν•¨μˆ˜λ“€μ΄ λͺ‡λ²ˆμ΄λ‚˜ λΆˆλ¦¬λŠ”κ±° μ •λ„λΌ μ•Œλ €μ£ΌλŠ” μœ ν‹Έλ¦¬ν‹°μ΄λ‹€. μ„±λŠ₯(performance)κ΄€μ μ—μ„œ 당신은 ν•¨μˆ˜κ°€ λͺ‡λ²ˆ λΆ„λ¦¬λŠ”κ°€μ— κ΄€ν•΄μ„œλŠ” 그리 큰 관심을 두지 μ•Šμ„ 것이닀. ν”„λ‘œκ·Έλž¨μ˜ μ‚¬μš©μž μˆ˜λΌ μ„Έκ±°λ‚˜, λ„ˆλ¬΄ λ§Žμ€ ꡬ문이 μˆ˜ν–‰λ˜μ–΄ λΆˆν‰μ„ λ°›λŠ” λΌμ΄λΈŒλŸ¬λ¦¬λΌ μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ μˆ˜λΌ μ„Έκ±°λ‚˜, ν˜Ήμ€ λ„ˆλ¬΄ λ§Žμ€ ν•¨μˆ˜λ“€μ΄ λΆˆλ¦¬λŠ” 것을 μ„ΈλŠ” 것은 λ‹€μ†Œ λ“œλ¬Έ 일이기도 ν•˜λ‹€. ν•˜μ§€λ§Œ λ§Œμ•½ λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄κ°€ 좩뢄이 λΉ λ₯΄λ‹€λ©΄ 아무도 μ‹€ν–‰λ˜λŠ” ꡬ문의 μˆ˜μ— κ΄€ν•΄ κ΄€μ—¬μΉ˜ μ•ŠλŠ”λ‹€. 그리고 λ§Œμ•½ λ„ˆλ¬΄ 느리면 λ°˜λŒ€κ² μ§€. (이후 λ¬Έμž₯이 λ„ˆλ¬΄ μ΄μƒν•΄μ„œ μƒλž΅, 바보 μž‘μ„±μž)

λͺ‡λ²ˆμ΄λ‚˜ ꡬ문이 μ‹€ν–‰λ˜λŠ”κ°€, ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜λŠ”κ°€λŠ” λ•Œλ•Œλ‘œ λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄ μ•ˆμ˜ λͺ¨μŠ΅μ„ 이야기 ν•΄μ€λ‹€. 예λΌλ“€μ–΄ λ§Œμ•½ λ‹Ήμ‹ μ΄νŠΉλ³„ν•œ ν˜•νƒœμ˜ κ°μ²΄λΌ μˆ˜λ°±κ°œλΌ λ§Œλ“ λ‹€κ³  ν•˜λ©΄, μƒμ„±μžμ˜ νšŸμˆ˜λΌ μ„ΈλŠ”κ²ƒλ„ μΆ©λΆ„νžˆ κ°’μ–΄μΉ˜ μžˆλŠ” 일일 것이닀. κ²Œλ‹€κ°€ ꡬ문과, ν•¨μˆ˜κ°€ λΆˆλ¦¬λŠ” μˆ«μžλŠ” λ‹Ήμ‹ μ—κ²Œ 직접적인 해결책은 μ œμ‹œ λͺ»ν•˜κ² μ§€λ§Œ, μ†Œν”„νŠΈμ›¨μ–΄μ˜ ν•œλ©΄μ„ μ΄ν•΄ν•˜λŠ”λ° 도움을 μ„것이닀. 예λΌλ“€μ–΄μ„œ λ§Œμ•½ 당신은 동적 λ©”λͺ¨λ¦¬ μ‚¬μš©μ„ ν•΄κ²°ν•˜κΈ° μœ„ν•œ 방법을 찾지 λͺ»ν•œλ‹€λ©΄ μ΅œμ†Œν•œ λͺ‡λ²ˆμ˜ λ©”λͺ¨λ¦¬ ν• λ‹Ήκ³Ό ν•΄μ œ ν•¨μˆ˜κ°€ λΆˆλ¦¬λŠ”κ²ƒμ„ μ•„κ²Œλ˜λŠ”κ²ƒμ€ μœ μš©ν•œ 도움을 μ„지도 λͺ¨λ₯Έλ‹€. (e.g., operators new, new[], delete and delete[] - Item 8μ°Έκ³ )

λ¬Όλ‘ ,ν”„λ‘œνŒŒμΌλŸ¬(profiler:λΆ„μ„μž)의 μž₯점은 ν”„λ‘œμ„ΈμŠ€μ€‘ λ°μ΄ν„°λΌ μž‘μ„μˆ˜ μžˆλ‹€λŠ” 점이닀. λ§Œμ•½ 당신이 λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ„ ν‘œν˜„λ˜μ§€ μ•ŠλŠ” μž…λ ₯ 값에 λŒ€ν•˜μ—¬ ν”„λ‘œνŒŒμΌ(κ°μ‹œ 정도 의λΈλ‘œ)ν•œλ‹€κ³  ν•˜λ©΄, ν”„λ‘œνŒŒμΌλŸ¬κ°€ λ³΄μ—¬μ€ λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄μ˜ λͺ¨μŠ΅μ—μ„œ λ³΄ν†΅μ˜ 속도와, 잘 κ²¬λ””λŠ” λͺ¨μŠ΅μ„ 보여μ€λ‹€λ©΄ - 그뢀뢄이 μ†Œν”„νŠΈμ›¨μ–΄μ˜ 80%일꺼닀. - λΆˆλ§ŒμžˆλŠ” κ΅¬μ—­μ—λŠ” μ ‘κ·Όν•˜μ§€ μ•Šμ„ λ‹€λŠ” 의λΈκ°€ λœλ‹€. ν”„λ‘œνŒŒμΌμ€ 였직 λ‹Ήμ‹ μ—κ²Œ ν”„λ‘œκ·Έλž¨μ˜ νŠΉλ³„λ‚œ 뢀뢄에 κ΄€ν•΄μ„œλ§Œ 이야기 ν• μˆ˜ μžˆλŠ”κ±Έ 기얡해라 κ·Έλž˜μ„œ λ§Œμ•½ 당신이 ν‘œν˜„λ˜μ§€ μ•ŠλŠ” μž…λ ₯ 데이터 값을 ν”„λ‘œνŒŒμΌ ν•œλ‹€λ©΄ 당신은 κ²‰μœΌλ‘œ λ“€μ–΄λ‚˜μ§€ μ•ŠλŠ” 값에 λŒ€ν•œ ν”„λ‘œνŒŒμΌλ‘œ λŒμ•„κ°€μ•Ό 할것이닀. 그것은 당신이 νŠΉλ³„ν•œ μ“°μž„μ„ μœ„ν•˜μ—¬ λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄λΌ μ΅œμ ν™” ν•˜λŠ”κ²ƒκ³Ό λΉ„μŠ·ν•˜λ‹€. 그리고 이것은 μ „μ²΄λΌ λ³΄λŠ” 일반적인 μ“°μž„ μ•„λ§ˆ 뢀정적인 μ˜μ–‘μ„ μ„것이닀.

이런 결과듀을 λ§‰λŠ”λ° μ΅œμ„ μ±…μ€ λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄μ— κ°€λŠ₯ν•œν•œ λ§Žμ€ 데이터 λ“€μ—κ²Œ ν”„λ‘œνŒŒμΌμ„ μ‹œλ„ν•˜λŠ”κ²ƒμ΄λ‹€. κ²Œλ‹€κ°€ 당신은 각 데이터듀이 μ†Œν”„νŠΈμ›¨μ–΄κ°€ κ·Έκ²ƒμ˜ ν΄λΌμ΄μ–ΈνŠΈλ“€(ν˜Ήμ€ μ΅œμ†Œν•œ κ°€μž₯ μ€‘μš”ν•œ ν΄λΌμΈνŠΈλ“€μ—κ²ŒλΌλ„)μ—κ²Œ μ‚¬μš©λ°©μ‹μ„ 잘 보여주도둝 ν™•μ‹ ν• μˆ˜ μžˆμ–΄μ•Όλ§Œ ν•œλ‹€. μž˜ν‘œν˜„λ˜λŠ” 데이터듀은 μ–»κΈ°κ°€ μš©μ΄ν•˜λ‹€ μ™œλƒν•˜λ©΄ ν”„λ‘œνŒŒμΌλ§ μ€‘μ—λŠ” 당신이 κ·Έλ“€μ˜ λ°μ΄ν„°λΌ μ‚¬μš©ν• μˆ˜ μžˆκΈ°λ•Œλ¬Έμ— λ§Žμ€ ν΄λΌμ΄μ–ΈνŠΈλ“€μ΄ μ’‹κΈ° λ•Œλ¬Έμ΄λ‹€. (λ­”μ†Œλ¦¬μ•Ό. --;) 당신은 λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄λΌ κ·Έλ“€κ³Ό λ§Œλ‚˜λ©΄μ„œ μ‘°μ •(tuning)을 할것이고, 그것이 였직 λ‹Ήμ‹ μ΄λ‚˜ ν΄λΌμ΄μ–ΈνŠΈλ“€ μ–‘μͺ½μ—κ²Œ 쒋은 방법이닀.

1.2. Item 17:Consider using lazy evaluation

  • Item 17:lazy evaluation의 μ“°μž„μ— λŒ€ν•˜μ—¬ 생각해 보자.

DeleteMe ) lazy evaluationμ΄λ‚˜ μ—¬λŸ¬ μš©μ–΄κ°€ λ§ˆλ•…ν•œ ν•œκΈ€λ§μ΄ μ—†μ–΄μ„œ 이후 μ˜λ¬Έμ„ 직접 μ“΄λ‹€. μ „λ°˜μ μΈ λ‚΄μš©μ΄ μ˜λΈ μ„λͺ…을 ν•˜λ‹€. --상λΌ

λŠ₯λ₯ (efficiency)의 κ΄€μ μ—μ„œ 졜고의 계산은 κ²°μ½” 아무것도 μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ”κ²ƒμ΄λ‹€. 말이 μ€ μ΄μƒν•œκ°€? 생각해 봐라 당신이 μ–΄λ–€ 일도 ν•„μš”μ—†μ„λ•Œ 이건 λ§žλŠ”κ±°λ‹€. μ™œ 당신은 λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ•ˆμ—μ„œ κ°€μž₯ μ²˜μŒμ— 그것을 μˆ˜ν–‰ν•˜λ € ν•˜λŠ”κ°€? 그리고 λ§Œμ•½ 당신이 μ–΄λ–€ 일을 μˆ˜ν–‰ν•˜κΈ°λΌ μ›ν• λ•Œ 당신은 κ·Έ μ½”λ“œμ˜ μ‹€ν–‰(excuting)을 ν”Όν• μˆ˜λŠ” μ—†μ„κΉŒ?

자 μ—¬κΈ°μ„œμ˜ μ—΄μ‡ (keyword)κ°€ λ°”λ‘œ lazy 이닀.

μš°λ¦¬κ°€ 어린이이고, λ‹Ήμ‹ μ˜ λΆ€λͺ¨λ‹˜λ“€μ΄ λ‹Ήμ‹ μ—κ²Œ 방을 치우라고 이야기 ν–ˆμ„λ•ŒλΌ κΈ°μ–΅ν•΄ 보자. λ§Œμ•½ 당신이 λ‚˜μ™€ κ°™λ‹€λ©΄ 말이지 λ‚œ λ‹Ήμž₯ "λ„€" ν•˜κ³  λŒ€λ‹΅ν•˜κ³  μ•„λ§ˆλ„ λ‹€μ‹œ λ‚΄κ°€ν•˜λ˜ λ‹€λ₯Έ 일을 ν• κΊΌλ‹€. 당신은 μ•„λ§ˆ 방을 μΉ˜μš°μ§€ μ•Šκ² μ§€. 사싀 방을 μΉ˜μš°λŠ” μž‘μ—…μ€ λ‹Ήμ‹ μ˜ 일의 μš°μ„ μˆœμœ„μ— λŒ€ν•œ μƒκ°μ—μ„œ λ§ˆμ§€λ§‰μ— μœ„μΉ˜ν•œλ‹€. - κ·ΈλŸ¬λ‹ˆκΉŒ. λ‹Ήμ‹ μ˜ λΆ€λͺ¨λ‹˜μ΄ 당신에 방에 λ‹€κ°€μ˜€λŠ” μ†Œλ¦¬λΌ λ“€μ„λ•Œ 말이지. 그리고 λ‚˜λ©΄ 당신은 전속λ ₯으둜 방으둜 λ›°μ–΄λ“€μ–΄κ°€ κ°€λŠ₯ν•œν•œ κ°€μž₯ 빨리 μΉ˜μš΄λ‹€. λ§Œμ—­ 당신이 ν–‰μš΄μ•„λΌλ©΄ λΆ€λͺ¨λ‹˜λ“€μ€ κ²°μ½” μ²΄ν¬λΌ μ•ˆν•˜μ‹œκ³  λ‹Ήμ‹ μ€μ΄λŸ° λͺ¨λ“  μΉ˜μš°λŠ” κ·€μ°μ€ μž‘μ—…μ„ 보톡 κΊΌλ¦°λ‹€.

이런 같은 관점을 이제 막 5λ…„μ°¨ C++ν”„λ‘œκ·Έλž˜λ¨Έμ— λŒ€μž… μ‹œμΌœλ³Έλ‹€. 컴퓨터 κ³Όν•™μ—μ„œ, μš°λ¦¬λŠ” κ·ΈλŸ¬ν•œ λ’€λ‘œ λΈλ£¨κΈ°λΌ λ°”λ‘œ lazy evaluation(ꡬ지 ν•΄μ„ν•˜λ©΄ ν•„μš”μ‹œ μ—°μ‚°, (졜)ν›„ μ—°μ‚°, λŠ¦μ€ 연산정도라 ν• μˆ˜ μžˆκ² λ‹€.)이라고 λ§ν•œλ‹€. 당신이 lazy evaluation을 μ‚¬μš©ν•˜λ©΄ λ‹Ήμ‹ μ˜ ν΄λž˜μŠ€λ“€μ΄ μ΅œμ’…μ μœΌλ‘œ μ›ν•˜λŠ” κ²°κ³Όκ°€ λ‚˜μ˜¬ μ‹œκ°„κΉŒμ§€ μ§€μ—°λ˜λŠ” 그런 μƒνƒœλ‘œ 코딩을 ν•΄μ•Ό ν•œλ‹€. λ§Œμ•½ 결과값을 κ²°κ΅­μ—λŠ” μš”κ΅¬ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄, 계산은 κ²°μ½” μˆ˜ν–‰λ˜μ§€ μ•Šμ•„μ•Ό ν•œλ‹€. 그리고 λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄μ˜ ν΄λΌμ΄μ–ΈνŠΈλ“€κ³Ό λ‹Ήμ‹ μ˜ λΆ€λͺ¨λ‹˜μ€ 더 ν˜„λͺ…ν•˜μ§€ μ•Šμ•„μ•Ό ν•œλ‹€.( 무슨 μ†Œλ¦¬λƒ ν•˜λ©΄, μœ„μ˜ 방치우기 이야기 처럼 λΆ€λͺ¨λ‹˜μ΄λ‚˜ ν΄λΌμ΄μ–ΈνŠΈλ“€μ΄ lazy evaluationκΈ°λ²•μ˜ 일처리둜 해결을 ν•˜μ§€ μ•Šμ•„λ„ μž‘μ—…μ— λŒ€ν•œ 신경을 μ•ˆμ¨μ•Ό ν•œλ‹€λŠ” μ†Œλ¦¬ )

μ•„λ§ˆ 당신은 λ‚΄κ°€ ν•œ 이야기듀에 λŒ€ν•˜μ—¬ 의문슀둜운 점이 μžˆμ„κ²ƒμ΄λ‹€. μ•„λ§ˆ λ‹€μŒμ˜ μ˜ˆμ œλ“€μ΄ 도움을 μ„것이닀. 자!, lazy evaluation은 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ μƒμ—μ„œ μˆ˜λ§Žμ€ 변화에 μ μš©ν• μˆ˜ μžˆλ‹€. κ·Έλž˜μ„œ λ‹€μŒκ³Ό 같이 4κ°€μ§€λΌ μ œμ‹œν•œλ‹€.

1.2.1. Reference Counting (μ°Έμ‘° μ„ΈκΈ°)

λ‹€μŒκ³Ό 같은 μ½”λ“œλΌ μƒκ°ν•΄ 봐라
~cpp 
    class String { ... };   // λ¬Έμžμ—΄ 클래슀 (이건 λ°‘μ˜ μ–ΈκΈ‰κ³Ό 같이 ν‘œμ€ μŠ€νŠΈλ§ νƒ€μž…κ³Ό 
                            // 같이 μ‚¬μš© 방식이 μ μš©λœλ‹€κ³  κ°€μ •ν•œλ‹€. ν•˜μ§€λ§Œ κ²°μ½” μ‘΄μž¬ν•˜μ§€λŠ” μ•ŠλŠ”λ‹€.)

    String s1 = "Hello";
    String s2 = s1;         // String 볡사 μƒμ„±μžλΌ λΆ€λ₯Έλ‹€.
String 볡사 μƒμ„±μžμ˜ μ μš©μ‹œ, s2λŠ” s1에 μ˜ν•˜μ—¬ μ΄ˆκΈ°ν™” λ˜μ–΄μ„œ s1κ³Ό s2λŠ” 각각 "Hello"λΌ κ°€μ§€κ²Œλœλ‹€. 그런 볡사 μƒμ„±μžλŠ” λ§Žμ€ λΉ„μš© μ†Œλͺ¨μ— κ΄€κ³„λ˜μ–΄ μžˆλŠ”λ°, μ™œλƒν•˜λ©΄, s1의 값을 s1둜 λ³΅μ‚¬ν•˜λ©΄μ„œ 보톡 heap λ©”λͺ¨λ¦¬ 할당을 μœ„ν•΄ new operator(Item 8μ°Έκ³ )λΌ s1의 λ°μ΄ν„°λΌ s2둜 λ³΅μ‚¬ν•˜κΈ° μœ„ν•΄ strcpyλΌ ν˜ΈμΆœν•˜λŠ” 과정이 μˆ˜ν–‰λ˜κΈ° λ•Œλ¬Έμ΄λ‹€. 이것은 eager evaluation(ꡬ지 ν•΄μ„ν•˜λ©΄ μ¦‰μ‹œ μ—°μ‚° 정도 일것이닀.) κ°œλ…μ˜ μ μš©μ΄λ‹€.:s1의 λ³΅μ‚¬λΌ μˆ˜ν–‰ ν•˜λŠ” 것과, s2에 κ·Έ λ°μ΄ν„°λΌ μ§‘μ–΄λ„£λŠ” κ³Όμ •, μ΄μœ λŠ” String의 볡사 μƒμ„±μžκ°€ 호좜되기 λ•Œλ¬Έμ΄λ‹€. ν•˜μ§€λ§Œ μ—¬κΈ°μ—λŠ” s2κ°€ 쓰여진적이 없이 μƒˆλ‘œ μƒμ„±λ˜λŠ” 것이기 λ•Œλ¬Έμ— μ‹€μ œλ‘œ s2에 κ΄€ν•΄μ„œ μ €λŸ° 일련의 볡사와, μ΄λ™μ˜ μ—°μ‚°μ˜ ν•„μš”μ„±μ΄ μ—†λ‹€.

lazy μ ‘κ·Ό 방법은 μ€λ” 훨씬 적은 μˆ˜ν–‰μ„ μ΄λˆλ‹€. s1의 λ³΅μ‚¬λ‘œ s2λΌ μ œκ³΅ν•˜κΈ° λŒ€μ‹ μ— s2κ°€ s1의 값을 κ³΅μœ ν•΄ λ²„λ¦¬λŠ” 것이닀.
μ§€κΈˆ μœ„μ—μ„œ μ΄λ ‡κ²Œ μ ‘κ·Όν•˜λŠ” 방식은 μž‘κ³ , κ°„λ‹¨ν•œ 뢀뢄을 μ–ΈκΈ‰ν•˜λŠ”κ±°μ— λΆˆκ³Όν•˜λ‹€ κ·Έλž˜μ„œ, λˆ„κ°€ 무엇을 κ³΅μœ ν–ˆλŠ”μ§€ μ•Œκ³  있고, λ°˜ν™˜λ˜λŠ” κ°’μœΌλ‘œ, μ–ΈκΈ‰ν•œ new와 볡사에 μΆ”κ°€λΉ„μš©λ˜λŠ” μ§€μΆœμ„ μ„μΌμˆ˜ μžˆλ‹€. s1,s2κ°€ κ³΅μœ ν•˜λŠ” 데이터 ꡬ쑰의 μƒνƒœλŠ” ν΄λΌμ΄μ–ΈνŠΈλ“€μ—κ²Œ λͺ…ν™•ν•˜λ‹€. 그리고 그것은 ν™•μ‹€νžˆ λ‹€μŒμ— μ œμ‹œλ  μ˜ˆμ œκ°™μ΄ 값을 쓰지 μ•Šκ³  μ½κΈ°λ§Œμ„ μš”κ΅¬ν• λ•ŒλŠ” μ•„λ¬΄λŸ° κ±±μ •ν•  점이 μ—†λ‹€.
~cpp 
    cout << s1;         // s1의 값을 μ½λŠ”λ‹€.
    cout << s1 + s2;    // s1κ³Ό s2의 값을 μ½λŠ”λ‹€.
사싀, 값을 κ³΅μœ ν•˜λŠ” μ‹œκ°„μ€ λ‘˜μ€‘ μ•„λ¬΄κ±°λ‚˜ 값이 μˆ˜μ •λ˜μ–΄ λ²„λ¦΄λ•Œ λ‹€λ₯Έμ μ΄ λ°œμƒν•˜κΈ° μ „κΉŒμ§€λ§Œ μœ νš¨ν•œ 것이닀. :γ…£κ·ΈλŸ°λ° μ–‘μͺ½μ΄ λ‹€ λ°”λ€κ²Œ μ•„λ‹ˆλΌ ν•œμͺ½λ§Œ λ°”λ€ŒλŠ” 이런 지적은 μ€‘μš”ν•œκ²ƒμ΄λ‹€. λ‹€μŒκ³Ό ꡬ문처럼
~cpp 
    s2.convertToUpperCase();
이건 s2의 κ°’λ§Œμ„ λ°”κΎΈκ³  s1μ—λŠ” 영ν–₯을 λΌμΉ˜μ§€ μ•Šμ€ μš”κ΅¬λ‘œ, 맀우 치λͺ…적이닀.

이와 같은 ꡬ문의 μ‚¬μš©μœΌλ‘œ, String의 convertToUpperCase ν•¨μˆ˜λΌ μ μš©ν•˜λ©΄, s2의 κ°’μ˜ 볡사본을 λ§Œλ“€μ–΄μ•Ό ν•˜κ³ , μˆ˜μ •λ˜κΈ°μ „μ— s2에 κ·Έκ±Έ s2의 μ’…μ†λ˜λŠ” λ°μ΄ν„°λ‘œ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€. convertToUpperCase 내뢀에 μš°λ¦¬λŠ” lazy μƒνƒœκ°€ 더이상 μ§€μ†λ˜μ§€ μ•Šλ„λ‘ ν•˜λŠ” μ½”λ“œλΌ λ„£μ–΄μ•Ό ν•œλ‹€.:s2κ°€ λ§ˆμŒλŒ€λ‘œ λ‹€λ£°μˆ˜ μžˆλ„λ‘ s2의 곡유된 κ°’μ˜ 사본을 볡사해야 ν•œλ‹€. λ°˜λ©΄μ— λ§Œμ•½ s2κ°€ κ²°μ½” μˆ˜μ •λ˜μ§€ μ•Šμ„ 것이라면, μ΄λŸ¬ν•œ s2만의 값을 λ³΅μ‚¬ν•˜λŠ” 일련의 과정이 ν•„μš” 없을 것이닀. 그리고 s2κ°€ μ‘΄μž¬ν•˜λŠ” 만큼 값도 계속 μ‘΄μž¬ν•΄μ•Ό ν•œλ‹€. λ§Œμ•½ 더 μ’‹κ²Œ, s2κ°€ μ•žμœΌλ‘œ κ²°μ½” λ³€ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄, μš°λ¦¬λŠ” κ²°μ½” κ·Έκ²ƒμ˜ 값에 λŒ€ν•œ λ…Έλ ₯을 ν• ν•„μš”κ°€ 없을 것이닀.

κ°’μ˜ κ³΅μœ μ— κ΄€ν•˜μ—¬ μ€λ” μžμ„Έν•˜κ²Œ 이 λ¬Έμ œμ— λ…Όμ˜λΌ μ œκ³΅ν•  뢀뢄은 Item 29(λͺ¨λ“  μ½”λ“œκ°€ λ“€μ–΄μžˆλ‹€.)에 μžˆλ‹€. ν•˜μ§€λ§Œ κ·Έ 생각 μ—­μ‹œ lazy evaluation이닀.:κ²°μ½” 당신이 μ •λ§λ‘œ 어떀것을 ν•„μš”ν•˜κΈ° μ „κΉŒμ§€λŠ” κ·Έκ²ƒμ˜ 사본을 λ§Œλ“œλŠ” μž‘μ—…μ„ ν•˜μ§€ μ•Šκ²ƒ. 일단 그보닀 lazy 해져봐라.- 어떀이가 당신이 그것을 μ œκ±°ν•˜κΈ° μ „κΉŒμ§€ 같은 μžμ›μ„ μ‹€μ»· μ‚¬μš©ν•˜λŠ”κ²ƒ. λͺ‡λͺ‡ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ˜μ—­μ—μ„œ 당신은 μ’…μ’… μ €λŸ¬ν•œ 비합리적 λ³΅μ‚¬μ˜ 과정을 μ˜μ›νžˆ μ œκ±°ν•΄ λ²„λ¦΄μˆ˜ μžˆμ„ 것이닀.

1.2.2. Distinguishing Read from Writes ( 읽기와 μ“°κΈ°μ˜ ꡬ뢄 )

reference-counting 을 ν† λŒ€λ‘œν•œ λ¬Έμžμ—΄μ˜ κ΅¬ν˜„ μ˜ˆμ œλΌ μ‘°κΈˆλ§Œ 생각해 보면 곧 lazy evaluation의 방법쀑 μš°λ¦¬λΌ λ•λŠ” λ‘λ²ˆμ§Έμ˜ 것을 λ§Œλ‚˜κ²Œ λœλ‹€. λ‹€μŒ μ½”λ“œλΌ μƒκ°ν•΄ 보자
~cpp 
    String s = "Homer's Iliad";     // λ‹€μŒ  λ¬Έμžμ—΄μ΄ reference-counting으둜 
                                    // κ΅¬ν˜„λ˜μ—ˆλ‹€κ³  μƒκ°ν•˜μž
    ...
    cout << s[3];       // operator []λΌ ν˜ΈμΆœν•΄μ„œ s[3]을 μ½λŠ”λ‹€.(read)
    s[3] = 'x';         // operator []λΌ ν˜ΈμΆœν•΄μ„œ s[3]에 μ“΄λ‹€.(write)
첫번째 operator[]λŠ” λ¬Έμžμ—΄μ„ μ½λŠ” 뢀뢄이닀,ν•˜μ§€λ§Œ λ‘λ²ˆμ§Έ operator[]λŠ” μ“°κΈ°λΌ μˆ˜ν–‰ν•˜λŠ” κΈ°λŠ₯을 ν˜ΈμΆœν•˜λŠ” 뢀뢄이닀. μ—¬κΈ°μ—μ„œ 읽기와 μ“°κΈ°λΌ κ΅¬λΆ„ν• μˆ˜ μžˆμ–΄μ•Ό ν•œλ‹€.(distinguish the read all from the write) μ™œλƒν•˜λ©΄ μ½κΈ°λŠ” refernce-counting κ΅¬ν˜„ λ¬Έμžμ—΄λ‘œμ„œ μžμ›(μ‹€ν–‰μ‹œκ°„ μ—­μ‹œ) μ§€λΆˆ λΉ„μš©μ΄ λ‚κ³ , μ•„λ§ˆ μ €λ ‡κ²Œ 슀트링의 μ“°κΈ°λŠ” μƒˆλ‘œμš΄ 볡사본을 λ§Œλ“€κΈ° μœ„ν•΄μ„œ 쓰기에 μ•žμ„œ λ¬Έμžμ—΄ 값을 쑰각내어야 ν•˜λŠ” μž‘μ—…μ΄ ν•„μš”ν•  것이닀.

DeleteMe ) λ‹¨λž€μ˜ ν›„λ°˜μ΄ μ•½κ°„ μ΄μƒν•˜λ‹€.
이것은 μš°λ¦¬μ—κ²Œ 적용 κ΄€μ μ—μ„œ μƒλ‹Ήνžˆ λ‚œμ œμ΄λ‹€. μš°λ¦¬κ°€ μ›ν•˜λŠ” 것에 이λ₯΄κΈ° μœ„ν•˜μ—¬ operator[] μ•ˆμͺ½μ— 각기 λ‹€λ₯Έ μž‘μ—…μ„ ν•˜λŠ” μ½”λ“œκ°€ ν•„μš”ν•˜λ‹€.(읽기와 쓰기에 λ”°λΌμ„œ λ”°λ‘œ μž‘λ™ν•΄μ•Ό ν•œλ‹€.) μ–΄λ–»κ²Œ μš°λ¦¬λŠ” operator[]κ°€ 읽기에 λΆˆλ¦¬λŠ”μ§€ 쓰기에 λΆˆλ¦¬λŠ”μ§€ κ²°μ •ν• μˆ˜ μžˆμ„κΉŒ? 이런 μž”μΈν•œ 사싀은 μš°λ¦¬λΌ λ‚œκ°ν•˜κ²Œ ν•œλ‹€. lazy evaluation의 μ‚¬μš©κ³Ό Item 30에 μ–ΈκΈ‰λœ proxy 클래슀(μœ„μž„ 클래슀, DPμ—μ„œμ˜ μ—­ν• κ³Ό λΉ„μŠ·ν• κ²ƒμ΄λΌ μ˜ˆμƒ) λŠ” μš°λ¦¬κ°€ μˆ˜μ •μ„ μœ„ν•˜μ—¬ μ½κΈ°λ‚˜ μ“°κΈ° 행동을 ν•˜λŠ”μ§€μ˜ 결정을 μ—°κΈ°ν•˜κ²Œ ν•œλ‹€.

1.2.3. Lazy Fetching ( λŠ¦μ€ κ°€μ Έμ˜€κΈ°)

lazy evaluationμ—μ„œ λ‹€λ£° μ„Έλ²ˆμ§Έμ˜ 주제둜, 당신이 λ§Žμ€ ν•„λ“œλ‘œ 이루어진 큰 객체듀을 μ‚¬μš©ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ 가지고 μžˆλ‹€κ³  상상해 봐라. 그런 객체듀은 λ°˜λ“œμ‹œ ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ•Œ μœ μ§€λ˜λ©°, λ‚˜μ€‘μ—λŠ” 데이터 베이슀 μ•ˆμ— μ €μž₯λœμ–΄μ§„λ‹€. 각각의 κ°μ²΄λŠ” 각 κ°μ²΄λΌ μ•Œμ•„λ³Όμˆ˜ 있고, μœ μΌμ„±μ„ 보μž₯ν•˜λŠ” 데이터 베이슀둜 λΆ€ν„° κ°μ²΄λΌ λΆˆλŸ¬μ˜¬λ•Œ μ’…λ₯˜λΌ μ•Œμ•„ 볼수 μžˆλŠ”, μ‹λ³„μž(identifier)λΌ κ°€μ§€κ³  μžˆλ‹€.(OODB 인가.) :
~cpp 
    class LargeObject {                 // 크고, 계속 μœ μ§€λ˜λŠ” 객체듀
    public:
        LargeObject(ObjectID id);       // λ””μŠ€ν¬μ—μ„œ 객체의 볡ꡬ(λΆ€λ₯΄κΈ°)

        cosnt string& field1() const;   // ν•„λ“œμƒμ˜ κ°’1
        int field2() const;             // ν•„λ“œμƒμ˜ κ°’2
        double field3() const;          // ...
        const string& field4() const;
        const string& field5() const;
        ...
    };
자 그럼 λ””μŠ€ν¬μ—μ„œ 볡ꡬ(μžλ£ŒλΌ λΆ€λ₯΄κΈ°)λ˜μ–΄μ§€λŠ” LargeObject의 λΉ„μš©μ„ 생각해 보자:
~cpp 
    void restoreAndProcessObject(ObjectID id)       // 객체 볡ꡬ
    {
        LargeObject object(id);
        ...
    }
LargeObject μΈμŠ€ν„΄μŠ€λ“€μ΄ 크기 λ•Œλ¬Έμ— 그런 κ°μ²΄μ—μ„œ λͺ¨λ“  λ°μ΄ν„°λΌ μ–»λŠ” 것은, λ§Œμ•½μ— νŠΉλ³„νžˆ 데이터 λ² μ΄μŠ€κ°€ 외뢀에 λ„€ν¬μ›Œν¬ μƒμ—μ„œ 자료 λ‘œλ“œκ°€ μžˆλ‹€λ©΄ 데이터 베이슀의 μž‘μ—…μ€ λΉ„μŒ€κ²ƒμ΄λ‹€. λͺ‡λͺ‡ μƒν™©μ—μ„œ λͺ¨λ“  데이터 λ² μ΄μŠ€λΌ μ½μ–΄λ“€μ΄λŠ” λΉ„μš©μ€ ν•„μš”κ°€ μ—†λ‹€. μ˜ˆλΌ λ“€μ–΄μ„œ λ‹€μŒμ˜ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ’…λ₯˜μ— κ΄€ν•˜μ—¬ 생각해 보자.
~cpp 
void restoreAndProcessObject(ObjectID id)
{
    LargeObject object(id);
    if (object.field2() == 0) {
        cout << "Object " << id << ": null field2.\n";
    }
}
이런 κ²½μš°μ—μ„œλŠ” 였직 field2의 κ°’λ§Œμ„ μš”κ΅¬ν•œλ‹€. λ”°λΌμ„œ λ‹€λ₯Έ ν•„λ“œλΌ λ‘œλ“œν•˜λŠ” μž‘μ—…μ€ ν•„μš”μ—†λŠ” μž‘μ—…μ΄ λ˜μ–΄ 진닀.

lazy 둜의 μ ‘κ·Όμ—μ„œ 이런 λ¬Έμ œλŠ” LargeObjectκ°€ λ§Œλ“€μ–΄ μ§ˆλ•Œ λ””μŠ€ν¬μ—μ„œ μ•„λ¬΄λŸ° λ°μ΄ν„°λΌ μ½μ–΄ 듀이지 μ•ŠλŠ” 것이닀. λŒ€μ‹ μ— 였직 객체의 "껍데기"(shell)만 λ§Œλ“€μ–΄ μ£Όκ³ , λ°μ΄ν„°λŠ” 객체 λ‚΄λΆ€μ—μ„œ νŠΉμ • λ°μ΄ν„°λΌ ν•„μš”λ‘œ ν• λ•Œλ§Œ 데이터 λ² μ΄μŠ€μ—μ„œ λ°μ΄ν„°λΌ λ³΅κ΅¬ν•˜λŠ” 것이닀. μ—¬κΈ° 그런 κ΄€μ μ—μ„œ "damand-paged" λ°©μ‹μœΌλ‘œ 객체 μ΄ˆκΈ°ν™”λΌ μ μš©ν•œ 방법이 μžˆλ‹€.
~cpp 
    class LargeObjectP
    pulic:
        LargeObject(ObjectID id);
            
        const string& field1() const;
        int field2() const;
        double field3() const;
        const string& field4() const;
        ...
    private:
        ObjectID oid;

        mutable string  *field1Value;   // μ•žμœΌλ‘œμ˜ "mutable"에 κ΄€ν•œ 토둠을 보라
        mutable int     *field2Value;
        mutable double  *field3Value;
        mutable string  *field4Value;
        ...
    };

    LargeObject::LargeObject(ObjectID id):oid(id), field1Value(0), field2Value(0), field3Value(0), ...
    {}

    const string& LargeObject::field() const
    {
        if (field1Value == 0){
            field1의 λ°μ΄ν„°λΌ μ½κΈ° μœ„ν•˜μ—¬ 데이터 λ² μ΄μŠ€μ—μ„œ ν•΄λ‹Ή λ°μ΄ν„°λΌ κ°€μ§€κ³  μ™€μ„œ
            field1Value κ°€ 그것을 κ°€λ¦¬ν‚€κ²Œ ν•œλ‹€.
        }
        return *field1Value;
    }
객체의 각 ν•„λ“œλŠ” ν•„μš”ν•œ λ°μ΄ν„°μ˜ ν¬μΈν„°λ‘œ ν‘œν˜„λ˜μ–΄ 있고, LargeObject의 μƒμ„±μžλŠ” null둜 μ΄ˆκΈ°ν™” λœλ‹€. 그런 null ν¬μΈν„°λŠ” 아직 데이터 λ² μ΄μŠ€μ—μ„œ ν•΄λ‹Ή ν•„λ“œμ˜ μ •λ³΄λΌ μ•ˆμ½μ—ˆλ‹€λŠ” κ±Έ 의λΈν•œλ‹€. λ°μ΄ν„°λΌ μ ‘κ·Όν•˜κΈ° 전에 LargeObject의 각 멀버 ν•¨μˆ˜λŠ” λ°˜λ“œμ‹œ 이 ν•„λ“œμ˜ ν¬μΈν„°λΌ κ²€μ‚¬ν•œλ‹€. λ§Œμ•½ 포인터가 null이라면 λ°μ΄ν„°λΌ μ‚¬μš©ν•˜κΈ° 전에 λ°˜λ“œμ‹œ 데이터 λ² μ΄μŠ€μ—μ„œ 읽어 μ˜¨λ‹€.

lazy fetching을 적용 ν•˜λ©΄, 당신은 λ°˜λ“œμ‹œ field1κ³Ό 같은 const멀버 ν•¨μˆ˜λΌ ν¬ν•¨ν•˜λŠ” μ–΄λ– ν•œ 멀버 ν•¨μˆ˜μ—μ„œ μ‹€μ œ 데이터 ν¬μΈν„°λΌ μ΄ˆκΈ°ν™”ν•˜λŠ” 과정이 ν•„μš”ν•œ λ¬Έμ œκ°€ λ°œμƒν•œλ‹€.(constλΌ λ‹€μ‹œ μž¬ν• λ‹Ή?) ν•˜μ§€λ§Œ μ»΄νŒŒμΌλŸ¬λŠ” 당신이 const 멀버 ν•¨μˆ˜μ˜ λ‚΄λΆ€μ—μ„œ 데이터 λ©€λ²„λΌ μˆ˜μ •ν•˜λ €κ³  μ‹œλ„ν•˜λ©΄ κΉŒλ‹€λ‘œμš΄(cranky) λ°˜μ‘μ„ 가진닀. κ·Έλž˜μ„œ 당신은 "쒋와, λ‚˜λŠ” λ‚΄κ°€ ν•΄μ•Ό 할것을 μ•Œκ³ μžˆμ–΄" λ§ν•˜λŠ” 방법을 가지고 μžˆμ–΄μ•Όλ§Œ ν•œλ‹€. κ°€μž₯ 쒋은 방법은 ν¬μΈν„°μ˜ ν•„λ“œλΌ mutable둜 μ„ μ–Έν•΄ λ²„λ¦¬λŠ” 것이닀. μ΄κ²ƒμ˜ 의λΈλŠ” μ–΄λ– ν•œ 멀버 ν•¨μˆ˜μ—μ„œλ„ ν•΄λ‹Ή λ³€μˆ˜λΌ κ³ μΉ μˆ˜ μžˆλ‹€λŠ” 의λΈλ‘œ, μ΄λ ‡κ²Œ μ–΄λ– ν•œ 멀버 ν•¨μˆ˜λ‚΄μ—μ„œλ„ μˆ˜ν–‰ν• μˆ˜ μžˆλ‹€. 이것이 LargeObjectμ•ˆμ— μžˆλŠ” ν•„λ“œλ“€μ— mutable이 λͺ¨λ‘ μ„ μ–Έλœ μ΄μœ μ΄λ‹€.

mutable ν‚€μ›Œλ“œλŠ” μ΅œκ·Όμ— C++에 μΆ”κ°€λ˜μ–΄μ„œ, λ‹Ήμ‹ μ˜ 벀더듀이 아직 지원 λͺ»ν•  κ°€λŠ₯성도 μžˆλ‹€. μ§€μ›ν•˜μ§€ λͺ»ν•œλ‹€λ©΄, 당신은 또 λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ μ»΄νŒŒμΌλŸ¬μ—κ²Œ const 멀버 ν•¨μˆ˜ ν•˜μ—μ„œ 데이터 멀버듀을 κ³ μΉ˜λŠ” λ°©μ•ˆμ΄ ν•„μš”ν•˜λ‹€. ν•œκ°€μ§€ κ°€λŠ₯ν•  법인 방법이 "fake this"의 접근인닀. "fake this"λŠ” thisκ°€ ν•˜λŠ” μ—­ν• μ²˜λŸΌ 같은 κ°μ²΄λΌ κ°€λ¦¬ν‚€λŠ” ν¬μΈν„°λ‘œ pointer-to-non-const(constκ°€ μ•„λ‹Œ 포인터)λΌ λ§Œλ“€μ–΄ λ‚΄λŠ” 것이닀. (DeleteMe μ•½κ°„ 이상) 당신이 데이터 λ©€λ²„λΌ μˆ˜μ •ν•˜κΈ°λΌ μ›ν•˜λ©΄, 당신은 이 "fake this" ν¬μΈν„°λΌ ν†΅ν•΄μ„œ μˆ˜μ •ν• μˆ˜ μžˆλ‹€.:
~cpp 
    class LargeObject {
    public:
        const string& field1() const;   // λ°”λ€Œμ§€ μ•ŠμŒ
        ...
    private:
        string *field1Value;        // mutable둜 μ„ μ–Έλ˜μ§€ μ•Šμ•˜λ‹€.
        ...                         // κ·Έλž˜μ„œ κ³Όκ±° μ»΄νŒŒμΌλŸ¬λŠ” 이걸 ν—ˆμš©ν•œλ‹€.
    };
    const string& LargeObject::field1() const
    {
        // 자 이것이 fake This 인데, μ € ν¬μΈν„°λ‘œ this에 λŒ€ν•œ μ ‘κ·Όμ—μ„œ constλΌ ν’€μ–΄ λ²„λ¦¬λŠ” 역할을 ν•œλ‹€.
        // LargeObject* ν•˜κ³  constκ°€ 뒀에 λΆ™μ–΄ 있기 λ•Œλ¬Έμ— LargeObject* μžμ²΄λŠ” constκ°€ μ•„λ‹Œ μ…ˆμ΄λ‹€. 
        LargeObject * const fakeThis = const_cast<LargeObject* const>(this);

        if( field1Value == 0){
            fakeThis->field1Value =         // fakeThis κ°€ constκ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ—
                λ°μ΄ν„°λ² μ΄μŠ€μ— μ ‘κ·Όν•΄μ„œ     // μ΄λŸ¬ν•œ μ‹œλ„λŠ” ν•©λ‹Ήν•˜λ‹€.
                ν¬μΈν„°λΌ λ„˜κΈ°λŠ” λΆ€λΆ„
        }
        return * field1Value;
    }
이 ν•¨μˆ˜λŠ” *this의 constnessμ„±μ§ˆμ„ λΆ€μ—¬ν•˜κΈ° μœ„ν•˜μ—¬ const_cast(Item 2μ°Έκ³ )λΌ μ‚¬μš©ν–ˆλ‹€.λ§Œμ•½ 당신이 const_cast마져 지원 μ•ˆν•˜λ©΄ λ‹€μŒκ³Ό 같이 ν•΄μ•Ό μ»΄νŒŒμΌλŸ¬κ°€ μ•Œμ•„ λ¨ΉλŠ”λ‹€.
~cpp 
    const string& LargeObject::field1() const
    {
        LargeObject * const fakeThis = (LargeObject* const)(this);
        ...
    }

자, 그럼 λ‹€μ‹œ ν•œλ²ˆ LargeObjectλ‚΄μ˜ 포인터듀에 κ΄€ν•˜μ—¬ 생각해 보자. μ‚¬μš©ν•˜κΈ°μ „μ— 각각의 포인터듀을 κ²€μ‚¬ν•˜λŠ” 것에 λΉ„ν•΄μ„œ, λͺ¨λ“  포인터듀이 null둜 μ΄ˆκΈ°ν™” λ˜μ–΄ μžˆλŠ”κ²ƒμ€ μ—λŸ¬μ˜ κ°€λŠ₯성을 가지고 μžˆλ‹€. λ‹€ν–‰νžˆλ„, 이런 μš°λ €λŠ” Item28의 smart pointers의 이용으둜 νŽΈμ΄μ„±μ„ μ œμ‹œν•œλ‹€. λ§Œμ•½ LargeObjectλ‚΄λΆ€μ—μ„œ smart pointerλΌ μ‚¬μš©ν•œλ‹€λ©΄ 당신은 μ•„λ§ˆλ„ 더이상 ν¬μΈν„°λΌ mutableν•˜κ²Œ μ„ μ–Έν•  ν•„μš”κ°€ 없을것이닀. 당신이 mutable을 ν•„μš”λ‘œ ν•˜λŠ” 상황이, smart pointerν΄λž˜μŠ€λ“€μ˜ 적용으둜 κ°€κΈ° λ•Œλ¬Έμ— μœ„μ˜ λ‚΄μš©μ€ μ€ μž„μ‹œμ μΈκ²ƒμ΄λ‹€. 이런 λ¬Έμ œμ— κ΄€ν•΄ ν•œλ²ˆ 생각해 봐라

  • Lazy Expression Evaluation ( ν‘œν˜„μ„ μœ„ν•œ 게으λ₯Έ μ—°μ‚° )
lazy evaluation이 가지고 μ˜€λŠ” λ§ˆμ§€λ§‰ μ˜ˆμ œλ‘œλŠ” λ°”λ‘œ 숫치 μ—°μ‚° μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜λ“€μ΄ λ¬Έμ œλΌ κ°€μ§€κ³  μ™”λ‹€. λ‹€μŒμ„ μ½”λ“œλΌ λ³΄μž
~cpp 
    template<class T>
    class Matrix { ... };

    Matrix<int> m1(1000, 1000);     // ꡉμž₯히 큰 intν˜• 1000x1000배열을 μ„ μ–Έν•œκ±°λ‹€.
    Matrix<int> m2(1000, 1000);
    ...
    Matrix<int> m3 = m1 + m2;       // 그리고 κ·Έ λ‘˜μ„ λ”ν•œλ‹€ ꡉμž₯ν•œ 연산이 ν•„μš”ν•΄μ§„λ‹€.
보톡 operator+에 λŒ€ν•œ κ΅¬ν˜„μ€ μ•„λ§ˆ eager evaluation(μ¦‰μ‹œ μ—°μ‚°) 이 될것이닀.;이런 κ²½μš°μ— 그것은 μ•„λ§ˆ m1κ³Ό m2의 리턴 값을 λŒ€μƒμœΌλ‘œ ν•œλ‹€. 이 계산(1,000,000 λ”ν•˜κΈ°)에 μ λ‹Ήν•œ κ²Œμ‚°μ–‘κ³Ό, λ©”λͺ¨λ¦¬ 할당에 λΉ„μš© 이 λͺ¨λ“œκ²ƒμ΄ μˆ˜ν–‰λ˜μ–΄μ Έμ•Ό 함을 λ§ν•œλ‹€.

lazy evaluaion λ°©λ²•μ—μ„œλŠ” 저건 λ„ˆλ¬΄ μ—„μ²­λ‚œ μˆ˜ν–‰μ„ ν•˜λŠ” 방법이라 ν•˜κ³ , κ·Έλž˜μ„œ 그것을 μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€. λŒ€μ‹ μ— m3내뢀에 m1κ³Ό m2의 합을 ν–ˆλ‹€λŠ” κ²ƒλ§Œμ„ κΈ°λŸ­ν•΄ λ‘”λ‹€. 그런 자료 κ΅¬μ‘°λŠ” μ•„λ§ˆλ„ m1κ³Ό m2λ‚˜ κ·Έμ΄μƒμ˜ λ”ν•˜κΈ°λΌ ν•˜κΈ° μœ„ν•œ 포인터 μ™Έμ—λŠ” μ•„λ¬΄λŸ° μ •λ³΄λΌ μœ μ§€ν•  ν•„μš”κ°€ 없을 것이닀. λͺ…λ°±νžˆ 이건 m1,m2에 λŒ€ν•œ μ‹€μ œ λ”ν•˜κΈ°λ³΄λ‹€ 훨씬 λΉ λ₯΄κ³  말할것도 없이 훨씬 적은 λ©”λͺ¨λ¦¬λΌ μ‚¬μš©ν•  것이닀.

ν”„λ‘œκ·Έλž¨μ΄ m3이후에 λ‹€μŒκ³Ό 같은 짓(이건 μ˜ˆμ œκ°€ μ—΄λ°›κ²Œν•΄μ„œ μ΄λ ‡κ²Œ μ“΄λ‹€.)을 저지λ₯Έλ‹€.
~cpp 
    Matrix<int> m4(1000, 1000);
    ...             // μ•„κΉŒ μœ„μ—μ„œ ν–ˆλ˜ m4에 μ–΄λ– ν•œ 값을 λ„£λŠ” μ½”λ“œλ“€μ΄λ‹€.
    m3 = m4 * m1;
μš°λ¦¬λŠ” 이제 μ•„κΉŒ m1, m2의 합인 m3λΌ μžƒμ–΄λ²„λ Έλ‹€.( 그리고 이건 ν•©μ˜ 계산 λΉ„μš©μ„ μ„μΈλ‹€λŠ” 의λΈλ„ λœλ‹€.) κ·Έκ²ƒμ—λŠ” m4,m1의 곱이 μƒˆλ‘œμš΄ κ°’μœΌλ‘œ κΈ°μ–΅λ˜μ–΄ 진닀. 말할 ν•„μš”λ„ 없이 이제 곱은 μˆ˜ν–‰μ•ˆν•˜λŠ” κ±°λ‹€. μ™œλƒ? μš°λ¦¬λŠ” lazy ν•˜λ‹ˆκΉŒ. ~

사싀 이건 λ©μ²­ν•œ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ 두 ν–‰λ ¬μ˜ 합을 κ³„μ‚°ν•˜κ³ , 그것을 μ‚¬μš©ν•˜μ§€ μ•Šμ•„μ„œ 얻은 이점을 λ…Έλ¦° μ–΅μ§€λ‘œ λ§Œλ“€μ–΄λ‚Έ 예제 같이 보인닀. λ©μ²­ν•œ ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” ν•„μš”λ„ ν•˜μ§€ μ•Šμ€ 계산을 μˆ˜ν–‰ν•œ 것이닀. ν•˜μ§€λ§Œ μœ μ§€λ³΄μˆ˜ 쀑에 보면, 이런 ν•„μš”μ—†λŠ” 계산을 μ΄ν–‰ν•˜λŠ” μˆ˜ν–‰μ½”λ“œλŠ” 그리 ν¬κ·€ν•˜μ§€λŠ” μ•Šλ‹€.

ν•˜μ§€λ§Œ, lazy evaluation이 치룬 μ‹œκ°„μ΄ 였직 μ €λŸ° μƒνƒœμΌ 뿐이라면, "μ—„μ²­λ‚œ 계산을 μš”κ΅¬ν•œλ‹€"λΌλŠ” λ¬Έμ œκ°€ 더 μ»€μ§ˆκ²ƒμ΄λΌκ³  μƒκ°ν•˜κΈ°λŠ” μ–΄λ ΅λ‹€.의 ν•„μš”μ„±μ΄ μ€λ” 일반적인 μ‹œλ‚˜λ¦¬μ˜€λŠ” μš°λ¦¬κ°€ 였직 κ³„μ‚°μ—μ„œμ˜ 일뢀가 ν•„μš”ν•œ κ²½μš°μ΄λ‹€. μ˜ˆλΌ λ“€μžλ©΄ μš°λ¦¬κ°€ m3λΌ m1κ³Ό m2의 ν•©μœΌλ‘œ μ΄ˆκΈ°ν™” ν–ˆλ‹€κ³  κ°€μ •ν•˜κ³  λ‹€μŒκ³Ό 같은 μ½”λ“œκ°€ μžˆλ‹€λ©΄
~cpp 
    cout << m3[4];  // m3의 4번째 μ—΄λ§Œμ„ μš”κ΅¬ν•œλ‹€.
ν™•μ‹€νžˆ μš°λ¦¬λŠ” 이제 lazy μƒνƒœλΌ λ²—μ–΄λ‚˜μ•Ό 함을 μ•Œμˆ˜ μžˆλ‹€.-μš°λ¦¬λŠ” m3의 4번째 열에 λŒ€ν•˜μ—¬ κ³„μ‚°λœ 값을 가지고 μžˆμ–΄μ•Ό ν•œλ‹€. κ·ΈλŸ¬λ‚˜, μ—­μ‹œλ‚˜ λ„ˆλ¬΄λ‚˜ μ§€λ‚˜μΉœ 것이닀. μš°λ¦¬λŠ” m3의 4번재 열을 κ³„μ‚°ν•΄μ•Όλ§Œ ν•˜λŠ”κ±΄ 말할 ν•„μš”λ„ μ—†λ‹€.:m3λŠ” 그것이 ν•„μš”ν•΄μ§€κΈ° μ „κΉŒμ§€λŠ” κ³„μ‚°ν• ν•„μš”κ°€ μ—†λ‹€. ν•˜μ§€λ§Œ ν–‰μš΄μœΌλ‘œ κ·Έλ ‡κ²Œ ν•  ν•„μš”κ°€ 없을것이닀.

DeleteMe ) λ‚΄μš©μ΄ μ΄μƒν•˜λ‹€. 보강 ν•„μš”
μ–΄λ–»κ²Œ ν–‰μš΄μ΄λƒκ΅¬? ν–‰λ ¬ κ³„μ‚°μ˜ 뢄야에 λŒ€ν•œ κ²½ν—˜μ΄ 우리의 μ΄λŸ¬ν•œ μ½”λ“œμ— λŒ€ν•œ λ…Έλ ₯에 κ°€λŠ₯성을 μ€λ‹€. 사싀 lazy evaluation은 APLμ΄λΌλŠ” 것에 κΈ°μ΄ˆν•˜κ³  μžˆλ‹€. APL은 1960λ…„λŒ€μ— μƒν˜Έ μž‘μš©μ˜(interactive) μ“°μž„μ„ μœ„ν•˜μ—¬ ν–‰λ ¬ 계산이 ν•„μš”ν•œ μ‚¬λžŒλ“€μ— μ˜ν•˜μ—¬ 개발된 것이닀. ν˜„μž¬λ³΄λ‹€ 떨어진 μˆ˜ν–‰λŠ₯λ ₯을 가진 μ»΄ν“¨ν„°μ—μ„œ APL은 λ”ν•˜κ³ , κ³±ν•˜κ³ , 심지어 μ»€λ‹€λž€ 행렬을 직접 λ‚˜λˆˆλŠ” κ²ƒμ²˜λŸΌ 보이게 ν•˜μ˜€λ‹€. κ·Έκ²ƒμ—λŠ” lazy evaluationμ΄λΌλŠ” λ°©λ²•μ΄μ—ˆλ‹€. κ·Έ 방법은 일반적으둜 보톡 νš¨μœ¨μ μ΄μ—ˆλ‹€. μ™œλƒν•˜λ©΄ APL μ‚¬μš©μžκ°€ 보톡 λ”ν•˜κ³ , κ³±ν•˜κ³  λ‚˜λˆ„λŠ” 것을 κ·Έκ²ƒμ˜ ν–‰λ ¬μ˜ 쑰각듀을 ν•„μš”λ‘œ ν•˜κ³ , μ „μ²΄μ˜ κ²°κ³Όκ°€ ν•„μš”ν•˜κΈ° μ „κΉŒμ§€ μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€. APL 은 lazy evaluation을 μ‚¬μš©ν•΄μ„œ ν–‰λ ¬μƒμ˜ κ²°κ³ΌλΌ μ •ν™•νžˆ μ•Œ ν•„μš”κ°€ μžˆμ„λ•ŒκΉŒμ§€ κ²Œμ‚°μ„ μ§€μ—°μ‹œν‚¨λ‹€. 그런 λ‹€μŒ 였직 ν•„μš”ν•œ λΆ€λΆ„λ§Œμ„ κ³„μ‚°ν•œλ‹€. μ‹€μ œλ‘œ 이것은 κ³Όκ±° μ—΄μ•…ν•œ μ»΄ν“¨ν„°μ˜ λŠ₯λ ₯ν•˜μ—μ„œ μ‚¬μš©μžλ“€μ΄ 계산 집약적인(λ§Žμ€ ν–‰λ ¬ 계산을 μš”ν•˜λŠ”) λ¬Έμ œμ— κ΄€ν•˜μ—¬ μƒν˜Έμ μœΌλ‘œ(κ²°κ³Όκ°’κ³Ό μˆ˜ν–‰ 식간에 ν•„μš” 값을 μœ„ν•΄μ„œ μ΅œλŒ€ν•œ μ‹€μ œ 연산을 μ„μ—¬λ‚˜κ°€κ²Œ) μˆ˜ν–‰λœλ‹€.ν˜„μž¬μ˜ 기계도 λΉ¨λΌμ‘Œμ§€λ§Œ, 데이터듀이 컀지고, μ‚¬μš©μžλ“€μ€ 참을성이 μ„μ–΄λ“€κΈ° λ•Œλ¬Έμ— μš”μ¦˜μ—λ„ 이런 lazy evaluation의 μž₯점을 μ΄μš©ν•œ ν–‰λ ¬ μ—°μ‚° λΌμ΄λΈŒλŸ¬λ¦¬λΌ μ‚¬μš©ν•œλ‹€.

laziness(κ²ŒμœΌλ¦„)은 λ•Œλ‘œ μ‹œκ°„μ„ μ•„λΌλŠ”λŒ€ μ‹€νŒ¨ν•œλ‹€. m3κ°€ μ΄λŸ°μ‹μœΌλ‘œ 쓰이면:
~cpp 
    cout << m3;     // m3의 λͺ¨λ“ κ²ƒμ„ μ°λŠ”λ‹€.
뭐 끝났닀. m3λΌ μœ„ν•œ λͺ¨λ“  값을 가지고 μžˆμ–΄μ•Ό ν•œλ‹€. λΉ„μŠ·ν•˜κ²Œ m3κ°€ μ˜μ‘΄ν•˜λŠ” 행렬듀쀑에 μˆ˜μ •λ˜λŠ”κ²ƒ 이 μžˆμ–΄λ„, μ¦‰μ‹œ 계산을 ν•„μš”λ‘œ ν•œλ‹€.
~cpp 
    m3 = m1 + m2;   // m3κ°€ m1,m2의 합인걸 κΈ°μ–΅ν•˜λΌ
    m1 = m4;        // 이제 m3λŠ” m2와 κ³Όκ±° m1의 합이 λœλ‹€.
그러λ€λ‘œ λͺ‡κ°€μ§€μ˜ m1에 λŒ€ν•œ 할당이 m3λΌ λ³€ν™”μ‹œν‚€μ§€ μ•ŠλŠ”λ‹€λŠ” 확신을 가지고 μžˆμ–΄μ•Ό ν•œλ‹€. Matrix<int>의 내뢀에 ν• λ‹Ήλœ operator 내뢀에 m3의 값이 m1의 계산 이전에 κ³„μ‚°λ˜μ–΄ μžˆκ±°λ‚˜, m1의 κ³Όκ±° 값에 λŒ€ν•œ 볡사본을 가지고 있고 m3λŠ” 그것에 μ˜μ‘΄ν•΄μ•Ό ν•œλ‹€. λ‹€λ₯Έ ν•¨μˆ˜λ“€λ„ μ΄λŸ¬ν•œ ν–‰λ ¬μ˜ 변경을 μœ„ν•˜μ—¬ λ‹€λ₯Έ ν˜•μ‹μ˜ ν•¨μˆ˜λ“€λ„ 이런 λΉ„μŠ·ν•œ 것을 κ°μ•ˆν•΄μ•Ό 할것이닀.

각 κ°’ κ°„μ˜ μ˜μ‘΄μ„±κ³Ό,;데이터 ꡬ쑰의 μœ μ§€λΌ μœ„ν•˜μ—¬, κ°’λ“€, μ˜μ‘΄μ„±μ΄λ‚˜ λ‘κ°€μ§€μ˜ κ²°ν•© 방법을 μ €μž₯ν•΄μ•Ό ν•œλ‹€.; 그리고 λ§Žμ€ 수치 계산이 ν•„μš”ν•œ λΆ„μ•Όμ—μ„œ 볡사, λ”ν•˜κΈ° ν• λ‹Ή, 같은 operator의 overload 것이 ν•„μš”ν•˜λ‹€. λ°˜λ©΄μ— lazy evaluation의 μ μš©μ€ ν”„λ‘œκ·Έλž¨ μ‹€ν–‰μ€‘μ—μ„œ 정말 λ§Žμ€ μ‹œκ°„λ“€κ³Ό λ§Žμ€ μžμ›λ“€μ„ μ•„λ‚„μˆ˜ μžˆλ‹€. κ·Έλž˜μ„œ lazy evaluation의 μ‘΄μž¬λΌ μ •λ‹Ήν™” μ‹œμΌœ μ„것이닀.

  • Summary (μš”μ•½)
이런 λ„κ°€μ§€μ˜ μ˜ˆμ œλŠ” lazy evaluation이 λ‹€μ–‘ν•œ μ˜μ—­μ—μ„œ ν™œμš©λ μˆ˜ μžˆμŒμ„ μ‹œμ‚¬ν•œλ‹€.:ν•„μš”μ—†λŠ” 객체의 볡제 ν”Όν•˜κΈ°, operator[]에 읽기와 μ“°κΈ°λΌ κ΅¬λΆ„ν•˜κΈ°, 데이터 베이슀 μƒμ—μ„œμ˜ ν•„μš”μ—†λŠ” 자료 μ½κΈ°λΌ ν”Όν•˜κΈ°, ν•„μš”μ—†λŠ” 수치 계산을 ν”Όν•˜κΈ°. κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  그것은 정말 ν›Œλ₯­ν•œ μƒκ°λ§Œμ€ μ•„λ‹ˆλ‹€. 단지 ν•΄μΉ˜μ›Œμ•Ό 할일을 λΈλ£¨μ–΄μ„œ μ²˜λ¦¬ν•˜λŠ” 것이기 λ•Œλ¬Έμ— λ§Œμ•½μ— λ‹Ήμ‹ μ˜ λΆ€λͺ¨κ°€ 계속 κ°μ‹œλΌ ν•œλ‹€λ©΄ 당신은 계속 그런 일듀을 ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€. λ§ˆμ°¬κ°€μ§€λ‘œ ν”„λ‘œκ·Έλž¨ μƒμ—μ„œλ„ λͺ¨λ“  연산듀이 ν•„μš”ν•˜λ‹€λ©΄ lazy evaluation은 μ–΄λ– ν•œ μžμ›μ˜ μ ˆμ•½λ„ λ˜μ§€ μ•ŠλŠ”λ‹€. 거기도 λ§Œμ•½ λ‹Ήμ‹ μ˜ λͺ¨λ“  계산이 λ°˜λ“œμ‹œ ν•„μš”ν•œ μ€‘μš”ν•œ 것듀이라면, lazy evaluation은 μ•„λ§ˆ μ²˜μŒμ— ν—ˆμƒ 데이터듀과 의쑴 관계같은 κ²ƒμ˜ μ²˜λ¦¬λΌ μœ„ν•˜μ—¬, μ‹€μ œλ³΄λ‹€ 더 λ§Žμ€ 연산을 ν•˜κ²Œλ˜μ–΄ μˆ˜ν–‰ μ†λ„λΌ λŠλ¦¬κ²Œ 할것이닀. lazy evaluation은 였직 λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄ μƒμ—μ„œ ν”Όν• μˆ˜ μžˆλŠ” 계산이 μ‘΄μž¬ν•  λ•Œλ§Œ 유용히 μ“°μΌμˆ˜ μžˆλ‹€.

C++에 μ•Œλ§žλŠ” lazy evaluation은 μ—†λ‹€. κ·ΈλŸ¬ν•œ κΈ°μˆ μ€ μ–΄λ– ν•œ ν”„λ‘œκ·Έλž˜λ° 언어에도 적용 될수 μžˆλ‹€. 그리고 λͺ‡λͺ‡ μ–Έμ–΄λ“€-APL, λͺ‡λͺ‡ νŠΉμ„±ν™”λœ Lisp, κ°€μƒμ μœΌλ‘œ 데이터 흐름을 λ‚˜νƒ€λ‚΄λŠ” λͺ¨λ“  μ–Έμ–΄λ“€-λŠ” μ–Έμ–΄μ˜ ν•œ μ€‘μš”ν•œ 뢀뢄이닀. κ·Έλ ‡μ§€λ§Œ μ£Όμš” ν”„λ‘œκ·Έλž˜λ°, C++같은 언어듀은 eager evaluationλΌ κΈ°λ³ΈμœΌλ‘œ μ±„μš©ν•œλ‹€. C++μ—μ„œλŠ” μ‚¬μš©μžκ°€ lazy evaluation의 μ μš©μ„ μœ„ν•΄ 맀우 μ ν•©ν•˜λ‹€. μ™œλƒν•˜λ©΄ μΊ‘μŠν™”λŠ” ν΄λΌμ΄μ–ΈνŠΈλ“€μ„ κΌ­ μ•Œμ§€ λͺ»ν•΄λ„ lazy evaluation의 μ μš©μ„ κ°€λŠ₯ν•˜κ²Œ λ§Œλ“€μ–΄ μ£ΌκΈ° λ•Œλ¬Έμ΄λ‹€.

μ΄μ œκΉŒμ§€ μ–ΈκΈ‰ν–ˆλ˜ 예제 μ½”λ“œλ“€μ„ λ‹€μ‹œ ν•œλ²ˆ 봐라 당신은 클래슀 μΈν„°νŽ˜μ΄μŠ€λ§Œμ΄ 주어진닀면 그것이 eager, lazy인지 μ•Œμˆ˜λŠ” 없을 것이닀. κ·Έκ²ƒμ˜ 의λΈλŠ” eager evaluation도 μ—­μ‹œ κ³§λ°”λ‘œ 적용 κ°€λŠ₯ν•˜κ³ , λ°˜λŒ€λ„ κ°€λŠ₯ν•˜λ‹€λŠ” 의λΈμ΄λ‹€. λ§Œμ•½, μ—°κ΅¬λΌ ν†΅ν•΄μ„œ 클래슀의 κ΅¬ν˜„μ—μ„œ 병λͺ© ν˜„μƒμ„ λ³΄μ΄λŠ” 뢀뢄이 보인닀면, 당신은 lazy evaluation의 μ „λž΅μ— κ·Όκ±°ν•œ μ½”λ“œλ“€μ„ 적용 ν• μˆ˜ μžˆμ„ 것이닀. λ‹Ήμ‹ μ˜ ν΄λΌμ΄μ–ΈνŠΈλ“€μ€ μ΄λŸ¬ν•œ λ³€ν™”κ°€ μ„±λŠ₯의 ν–₯μƒμœΌλ‘œ 밖에 보이지 μ•ŠλŠ”λ‹€. 고객(ν΄λΌμ΄μ–ΈνŠΈλ“€)듀이 μ’‹μ™€ν•˜λŠ” μ†Œν”„νŠΈμ›¨μ–΄ ν–₯μƒμ˜ 방법, 당신이 μžλž‘μŠ€λ‘œμ›Œν•˜λŠ” lazyκ°€ 될수 μžˆλ‹€. (DeleteMe λͺ¨ν˜Έ)

1.3. Item 18: Amortize the cose of expected computations.

  • Item 18: μ˜ˆμƒλ˜λŠ” μ—°μ‚°μ˜ 값을 계산해 두어라.

Item 17μ—μ„œ κ°€λŠ₯ν•œν•œ 할일을 λ’€λ‘œ λΈλ£¨μ–΄λ‘λŠ”, lazy(κ²ŒμœΌλ¦„)λŒ€ν•œ μ›λ¦¬λΌ κ·Ήμ°¬ν•΄ λ‘μ—ˆλ‹€. 그리고 lazyκ°€ λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ˜ νš¨μœ¨μ„±μ„ μ¦λŒ€μ‹œν‚¬μˆ˜ μžˆλŠ” 방법에 λŒ€ν•˜μ—¬ μ„λͺ…ν•˜μ˜€λ‹€. 이번 itemμ—μ„œλŠ” λ°˜λŒ€μ˜ μž…μž₯을 μ„λͺ…ν•  생각이닀. μ—¬κΈ°μ—λŠ” laziness(κ²ŒμœΌλ¦„)μ΄λž€ μ—¬μ§€λŠ” μ—†λ‹€. μ—¬κΈ°μ—μ„œ λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄κ°€ 그것이 μš”κ΅¬ν•˜λŠ”κ²ƒ 보닀 더 λ§Žμ€ 일을 ν•΄μ„œ, μ„±λŠ₯ν–₯성에 도움을 μ„μˆ˜ μžˆλŠ”κ²ƒμ„ 보일것이닀. 이번 item의 철학이라고 ν•œλ‹€λ©΄ over-eager evaluation 이라고 ν‘œν˜„ν• μˆ˜ μžˆλ‹€.:μ–΄λ–€ λ°μ΄ν„°λΌ μš”κ΅¬ν•˜κΈ°λ„ 전에 λΈλ¦¬ 계산해 λ†“λŠ”κ²ƒ.

자, λ‹€μŒ μ˜ˆμ œλΌ μƒκ°ν•΄ 보자. 수치 λ°μ΄ν„°μ˜ 큰 calloections을 λ‚˜νƒ€λ„λŠ” ν΄λž˜μŠ€λ“€μ„ μœ„ν•œ ν…œν”Œλ¦Ώμ΄λ‹€.
~cpp 
    template<class NumericalType>
    class DataColletion {
    public:
        NumericalType min() const;
        NumericalType max() const;
        NumericalType avg() const;
        ...
    }
min, max, avg에 ν•¨μˆ˜λŠ” ν˜„μž¬μ˜ ν•΄λ‹Ή collection의 μ΅œμ†Œκ°’, μ΅œλŒ€κ°’ 평균을 λ°˜ν™˜ν•˜λŠ” 값이라고 생각해라, μ—¬κΈ°μ—μ„œ 이듀이 κ΅¬ν˜„λ μˆ˜ μžˆλŠ” 방법은 3가지 정도가 μžˆλ‹€. eager evaluation(μ¦‰μ‹œμ—°μ‚°)을 μ΄μš©ν•΄μ„œ min, max, avgκ°€ ν˜ΈμΆœλ λ•Œλ§ˆλ‹€ ν•΄λ‹Ή 연산을 ν•˜λŠ” 방법. lazy evaluation(게으λ₯Έμ—°μ‚°)을 ν•΄μ„œ ν•΄λ‹Ή ν•¨μˆ˜κ°’μ΄ λ°˜ν™˜ν•˜λŠ” 값이, μ‹€μ œλ‘œ 연산에 ν•„μš”ν• λ•Œ λ§ˆμ§€λ§‰μ— κ³„μ‚°μ—μ„œ μ—°μ‚°ν•΄μ„œ 값을 μ–»λŠ” 방법. 그리고 over-eager evaluation(λΈλ¦¬μ—°μ‚°)을 μ΄μš©ν•΄μ„œ μ•„μ˜ˆ 싀행쀑에 μ΅œμ†Œκ°’, μ΅œλŒ€κ°’, 평균값을 collection내뢀에 가지고 μžˆμ–΄μ„œ min, max, avgκ°€ 호좜되면 μ¦‰μ‹œ 값을 μ œκ³΅ν•˜λŠ” 방법-μ–΄λ– ν•œ 계산도 ν•„μš” 없이 κ·Έλƒ₯ μ¦‰μ‹œ λŒλ¦¬λŠ”κ±°λ‹€. λ§Œμ•½ min, max, avgκ°€ 자주 ν˜ΈμΆœλœλ‹€λ©΄ collection의 μ΅œμ†Œκ°’, μ΅œλŒ€κ°’, 평균값을 μ΄μš©ν•˜λŠ” ν•¨μˆ˜λ“€μ΄ collection 전역에 κ±Έμ³μ„œ 계산을 ν•„μš”λ‘œ ν• μˆ˜ μžˆλ‹€. κ·Έλ ‡λ‹€λ©΄ 이런 κ³„μ‚°μ˜ λΉ„μš©μ€ eager,lazy evaluaton(게으λ₯Έμ—°μ‚°, μ¦‰μ‹œμ—°μ‚°)에 λΉ„ν•˜μ—¬ μ €λ ΄ν•œ λΉ„μš©μ„ μ§€μΆœν•˜κ²Œ 될것이닀.(ν•„μš”κ°’μ΄ μ¦‰μ‹œ λ°˜ν™˜λ˜λ‹ˆ)

이런 일을 ν–‰ν•˜λŠ”λ°μ— κ°€μž₯ κ°„λ‹¨ν•œ 방법은 μ΄λΈ κ³„μ‚°λœ 값을 μ €μž₯μ‹œμΌœ 놓고, λ‹€μ‹œ ν•„μš”λ‘œν• λ•Œ μ“°λŠ”κ±°λ‹€. 예λΌλ“€μ–΄ 당신이 직원듀에 κ΄€ν•œ μ •λ³΄λΌ μ œκ³΅ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“ λ‹€κ³  κ°€μ •ν•˜μž, 그리고 당신이 자주 쓰인닀고 μ˜ˆμƒν• μˆ˜ μžˆλŠ” 정보쀑 ν•˜λ‚˜λŠ” μ§μ›λ“€μ˜ 개인방(사무싀 or μΉ¨μ‹€ or μˆ™μ†Œ) 번호 이닀. 거기에 μ§μ›λ“€μ˜ μ •λ³΄λŠ” 데이터 λ² μ΄μŠ€μ— μ €μž₯λ˜μ–΄ μžˆλ‹€κ³  κ°€μ •ν•œλ‹€. ν•˜μ§€λ§Œ λŒ€λ‹€μˆ˜(당신이 μž‘μ„±ν•˜λŠ”κ±° 말고) ν”„λ‘œκ·Έλž¨μ„ μœ„ν•˜μ—¬ μ§μ›λ“€μ˜ 개인방 λ²ˆν˜ΈλŠ” 잘 쓰이지 μ•ŠλŠ”λ‹€. κ·Έλž˜μ„œ 데이터 λ² μ΄μŠ€μ—μ„œ 그것을 μ°ΎλŠ” 방법에 κ΄€ν•œ μ΅œμ ν™”κ°€ λ˜μ–΄ μžˆμ§€ μ•Šλ‹€. 당신은 μ§μ›λ“€μ˜ 개인방 λ²ˆν˜ΈλΌ λ°˜λ³΅μ μœΌλ‘œ μš”κ΅¬ν•˜λŠ” 것에 λŒ€ν•œ 데이터 λ² μ΄μŠ€κ°€ λ°›λŠ” κ³Όλ„ν•œ μŠ€νŠΈλ ˆμŠ€μ— μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜λ‹¨μ—μ„œ νŠΉμˆ˜ν•œ ꡬ쑰둜 λ§Œλ“œλŠ” κ±Έ ν”Όν•˜λ €λ©΄, findCubicleNumber ν•¨μˆ˜λ‘œμ„œ 개인방 λ²ˆν˜ΈλΌ μΊμ‹œ(μž„μ‹œμ €μž₯) μ‹œμΌœ λ†€μˆ˜ μžˆλ‹€. μ΄λΈ κ°€μ§€κ³  μžˆλŠ” 개인방 λ²ˆν˜Έμ— λŒ€ν•˜μ—¬ μ—°μ†μ μœΌλ‘œ λΆˆλ¦¬λŠ” μš”κ΅¬λŠ” 데이터 λ² μ΄μŠ€μ— 맀번 쿼리(query)λΌ λ‚ λ¦¬λŠ”κ²ƒλ³΄λ‹€λŠ” μΊμ‰¬λΌ μ‘°μ‚¬ν•˜μ—¬ 값을 λ§Œμ± μ‹œν‚¬μˆ˜ μžˆλ‹€.

μ—¬κΈ° findCubicleNumberλΌ μ μš©μ‹œν‚€λŠ” ν•œ 방법이 μžˆλ‹€.;그것은 지역(local)μΊμ‰¬λ‘œ STL의(Standard Template Library-Item 35 μ°Έκ³ ) map κ°μ²΄λΌ μ‚¬μš©ν•œλ‹€.
~cpp 
    int findCubicleNumber(const string& employeesName)
    {
        // static으둜 map을 μ„ μ–Έν•˜λŠ” κ³Όμ • 이 맡이 local cashe이닀.
        typedef map<string, int> CubicleMap;
        static CubicleMap cubes;

        // ν•΄λ‹Ή 직원 이름을 λ°”νƒ•μœΌλ‘œ cacheμ—μ„œ μ°ΎλŠ” κ³Όμ •
        // STL interator "it"은 ν•΄λ‹Ή entryλΌ μ°ΎλŠ”λ‹€.
        CubicleMap::iterator it = cubes.find(employeeName);

        // λ§Œμ•½ μ•„λ¬΄λŸ° entryλΌ μ°Ύμ„μˆ˜ μ—†λ‹€λ©΄, "it"의 값은 cubes.end이닀.
        // 그런 κ²½μš°μ—λŠ” dbμ—μ„œ μžλ£ŒλΌ κ°€μ§€κ³  와야 ν•œλ‹€.
        if(it == cubes.end()){
            int cubicle = 
                   직원 μ΄λ¦„μ˜ 개인방 λ²ˆν˜ΈλΌ λ°μ΄ν„° λ² μ΄μŠ€μ—μ„œ 
                   μ–»μ–΄μ˜€λŠ” κ³Όμ •
            
            cubes[employeeName] = cubicle;  // μΆ”κ°€
            return cubicle;
        }
        else {
            // "it" ν¬μΈν„°λŠ” μ •ν™•ν•œ cache entryλΌ κ°€λ¦¬ν‚€λ©° cubicleλ²ˆν˜ΈλŠ” λ‘λ²ˆμ§Έ 인자라
            // 이런 λ°©λ²•μœΌλ‘œ μ–»λŠ”λ‹€.
            return (*it).second;
        }
    }
STLμ½”λ“œλΌ μžμ„Ένžˆ μ•Œκ³  μ‹Άμ–΄μ„œ 촛점을 λ²—μ–΄λ‚˜μ§€ 말아라. Item 35 보면 μ€ ν™•μ‹€νžˆ μ•Œκ²Œ 될것이닀. λŒ€μ‹ μ— 이 ν•¨μˆ˜μ˜ 전체적인 κΈ°λŠ₯에 촛점을 λ§žμΆ”μ–΄ 보자.ν˜„μž¬ 이 방법은 비ꡐ적 λΉ„μ‹Ό 데이터 베이슀의 쿼리(query)λ¬Έμ—λŒ€ν•œ λΉ„μš©λŒ€μ‹ μ— μ €λ ΄ν•œ λ©”λͺ¨λ¦¬μƒμ˜ 데이터 베이슀 κ΅¬μ‘°μ—μ„œ 검색을 ν•˜λŠ” κ²ƒμœΌλ‘œ κ΅μ²΄ν•˜λŠ”κ±Έλ‘œ 볼수 μžˆλ‹€. 개인 λ°©λ²ˆν˜Έμ— λŒ€ν•œ 호좜이 ν•œλ²™ μ΄μƒμΌλ•Œ findCubicleNumberλŠ” 개인방 λ²ˆν˜Έμ— λŒ€ν•œ 정보 λ°˜ν™˜μ˜ 평균 λΉ„μš©μ„ λ‚μΆœμˆ˜ μžˆλ‹€. (ν•œκ°€μ§€ 쑰금 μžμ„Ένžˆ μ„λͺ…ν•˜μžλ©΄, λ§ˆμ§€λ§‰ κ΅¬λ¬Έμ—μ„œ λ°˜ν™˜λ˜λŠ” κ°’ (*it).second이 평범해 λ³΄μ΄λŠ” it->second λŒ€μ‹ μ— μ“°μ˜€λ‹€. μ™œ? λŒ€λ‹΅μ€ STL에 μ˜ν•œ 관행이라고 ν• μˆ˜ μžˆλŠ”λ°, λ°˜ν™˜μž(iterator)인 it은 객체이고 포인터가 μ•„λ‹ˆλΌλŠ” κ°œλ…, κ·Έλž˜μ„œ ->을 it에 μ μš©ν• μˆ˜ μžˆλ‹€λΌλŠ” 보μž₯이 μ—†λ‹€. STL은 "."κ³Ό "*"λΌ interatorμƒμ—μ„œ μ›ν•œλ‹€. κ·Έλž˜μ„œ (*it).secondλΌλŠ” 문법이 μ•½κ°„ 어색해도 μ“Έμˆ˜ μžˆλŠ” 보μž₯이 μžˆλ‹€.)

μΊμ‹œ(cashing)λŠ” μ˜ˆμƒλ˜λŠ” μ—°μ‚° 값을 기둝해 λ†“λŠ” ν•˜λ‚˜μ˜ 방법이닀. λΈλ¦¬ 가지고 μ˜€λŠ” 것이기도 ν•˜λ‹€. 당신은 λŒ€λŸ‰μ˜ 계산을 μ„μ΄λŠ” 것과 λ™λ“±ν•œ νš¨κ³ΌλΌ μ–»μ„κ²ƒμ΄λΌ μƒκ°ν• μˆ˜ μžˆλ‹€. 예λΌλ“€μ–΄μ„œ, Disk controllerλŠ” ν”„λ‘œκ·Έλž˜λ¨Έκ°€ 였직 μ†ŒλŸ‰μ˜ λ°μ΄ν„°λ§Œμ„ 원함함에도 λΆˆκ΅¬ν•˜κ³  λ°μ΄ν„°λΌ μ–»κΈ°μœ„ν•΄ λ””μŠ€ν¬λΌ μ½μ–΄ λ‚˜κ°ˆλ•Œ, 전체 λΈ”λ‘μ΄λ‚˜ μ½κ±°λ‚˜, 전체 μ„Ήν„°λΌ μ½λŠ”λ‹€. μ™œλƒν•˜λ©΄ 각기 μ—¬λŸ¬λ²ˆ ν•˜λ‚˜ λ‘κ°œμ˜ μž‘μ€ 쑰각으둜 μ½λŠ”κ²ƒλ³΄λ‹€ ν•œλ²ˆ 큰 쑰각의 λ°μ΄ν„°λΌ μ½λŠ”κ²Œ 더 λΉ λ₯΄κΈ° λ•Œλ¬Έμ΄λ‹€. κ²Œλ‹€κ°€, μ΄λŸ¬ν•œ κ²½μš°λŠ” μš”κ΅¬λ˜λŠ” 데이터가 ν•œκ³³μ— λͺ°λ €μžˆλ‹€λŠ” κ±Έ 보여주고, μ΄λŸ¬ν•œ κ²½μš°κ°€ 맀우 μΌλ°˜μ μ΄λΌλŠ” 것 μ—­μ‹œ λ°˜μ¦ν•œλ‹€. 이 것은 locality of reference (지역 데이터에 λŒ€ν•œ μ°Έμ‘°, μ—¬κΈ°μ„œλŠ” λ°μ΄ν„°λΌ μ–»κΈ°μœ„ν•΄ λ””μŠ€ν¬μ— 직접 μ ‘κ·Όν•˜λŠ”κ±Έ 의λΈν•˜λŠ”λ“) κ°€ 쒋지 μ•Šκ³ , μ‹œμŠ€ν…œ μ—”μ§€λ‹ˆμ–΄μ—κ²Œ λ©”λͺ¨λ¦¬ 케쉬와, κ·Έμ™Έμ˜ λΈλ¦¬ 데이터 가지고 μ˜€λŠ” 과정을 μ„λͺ…ν•˜λŠ” κ·Όκ±°κ°€ λœλ‹€.

λ­μ‹œλΌ?(Excuse me?) 당신은 disk controller와 CPU cash같은 μ € λ°‘μ—μ„œ 처리(low-level)ν•˜λŠ” μ²˜λ¦¬ν•˜λŠ” 일에 κ΄€ν•΄μ„œλŠ” μ‹ κ²½ μ•ˆμ“°λŠ” 거라고? κ±±μ • λ§ˆμ‹œλΌ(No problem) λΈλ¦¬ κ°€μ Έμ˜€κΈ°(prefetching) 당신이 높은 수μ€(high-level)μ—μ„œ ν• λ•Œ μ—­μ‹œ μ•ΌκΈ°λ˜λŠ” λ¬Έμ œμ΄λ‹ˆκΉŒ. 예λΌλ“€μ–΄, 상상해 봐라 당신은 동적 배열을 μœ„ν•˜μ—¬ ν…œν”Œλ¦Ώμ„ μ μš©ν–ˆλ‹€. ν•΄λ‹Ή 배열은 1μ—μ„œ λΆ€ν„° μžλ™μœΌλ‘œ ν™•μž₯λ˜λŠ” 건데, κ·Έλž˜μ„œ λͺ¨λ“  μžλ£Œκ°€ μžˆλŠ” ꡬ역은 ν™œμ„±ν™”λœ 것이닀.: (DeleteMe μ€ μ΄μƒν•¨)
~cpp 
    template<class T>           // 동적 λ°°μ—΄ T에 κ΄€ν•œ 클래슀 ν…œν”Œλ¦Ώ
    class DynArray { ... };

    DynArray<double> a;         // 이런 κ΄€μ μ—μ„œ a[0]은 합법적인 
                                // λ°°μ—΄ μΈμžμ΄λ‹€.
    a[22] = 3.5;                // aλŠ” μžλ™μ μœΌλ‘œ ν™•μž₯λ˜μ—ˆμœΌλ©°, 
                                // ν˜„μž¬λŠ” 0-22κΉŒμ§€μ˜ μ˜μ—­μ„ 가진닀.

    a[32] = 0;                  // λ‹€μ‹œ ν™•μž₯되며 이제 0-32κΉŒμ§€λ‹€.
μ–΄λ–»κ²Œ DynArray 객체가 ν•„μš”ν• λ•Œ λ§ˆλ‹€ 슀슀둜 ν™•μž₯λ˜λŠ” 걸까? 곧μž₯ μƒκ°ν• μˆ˜ μžˆλŠ”κ±΄ 그것이 μƒˆλ‘œμš΄ λ©”λͺ¨λ¦¬κ°€ ν•„μš”λ λ•Œλ§Œ ν• λ‹Ήλ˜κ³ λŠ” 것이닀 μ΄λŸ°κ²ƒ 처럼 말이닀.
~cpp 
templace<class T>
T& DynArray<T>::operator[](int index)
{
    if (index < 0) {
        μ˜ˆμ™ΈλΌ λ˜μ§„λ‹€.;
    }
    if (index > ν˜„μž¬ 인덱슀의 μ΅œλŒ€κ°’){
        newλΌ ν˜ΈμΆœν•΄μ„œ μΆ©λΆ„ν•œ λ©”λͺ¨λ¦¬λΌ ν™•λ³΄ν•œλ‹€.  κ·Έλ ‡κ²Œ ν•΄μ„œ indexλΌ ν™œμ„±ν™” μ‹œν‚¨λ‹€.;
    }
    return λ°°μ—΄μ˜ 인덱슀 μΈμžλΌ λ°˜ν™˜ν•œλ‹€.
μ΄λŸ¬ν•œ 접근은 newλΌ λ°°μ—΄μ˜ 증가 λ•Œλ§Œ λΆ€λ₯΄λŠ” κ°„λ‹¨ν•œ 방법 μ΄μ§€λ§Œ newλŠ” operator new(Item 8μ°Έκ³ )λΌ λΆ€λ₯΄κ³ , operator new(그리고 operaotr delete)λŠ” 보톡 이 λͺ…령어듀은 λΉ„μš©μ΄ λΉ„μ‹Έλ‹€. κ·Έκ²ƒμ˜ μ΄μœ λŠ” 일반적으둜 OS, μ‹œμŠ€ν…œ 기반의 호좜(System call)이 in-process ν•¨μˆ˜ν˜ΈμΆœ 보닀 느린게 λ˜κ² λ‹€. (DeleteMe OSλΌ λ°°μ›Œμ•Ό ν™•μ‹€νžˆ μ•Œκ² λ‹€ 이건) 결과적으둜 κ°€λŠ₯ν•œ system 호좜(system call)을 μ„μ—¬ λ‚˜κ°€μ•Ό ν•œλ‹€.

over-eager evaluation(μ„ μ—°μ‚°,λΈλ¦¬μ—°μ‚°) μ „μˆ μ€ 이 κ²ƒμ—λŒ€ν•œ 닡을 μ œμ‹œν•œλ‹€.:λ§Œμ•½ μš°λ¦¬κ°€ index iλ‘œμ„œ ν˜„μž¬μ˜ λ°°μ—΄μƒμ˜ ν¬κΈ°λΌ λŠ˜λ¦¬λ €λ©΄, locality of reference κ°œλ…μ€ μš°λ¦¬κ°€ μ•„λ§ˆ 곧 index i보닀 더 큰 κ³΅κ°„μ˜ ν•„μš”λ‘œ ν•œλ‹€λŠ”κ±Έ 이야기 ν•œλ‹€. 이런 λ‘λ²ˆμ§Έ (μ˜ˆμƒλ˜λŠ”)ν™•μž₯에 λŒ€ν•œ λ©”λͺ¨λ¦¬ ν• λ‹Ήμ˜ λΉ„μš©μ„ ν”Όν•˜κΈ° μœ„ν•΄μ„œλŠ” μš°λ¦¬λŠ” DynArray의 i의 크기가 μš”κ΅¬λ˜λŠ” 것에 λΉ„ν•΄μ„œ 쑰금 더 λ§Žμ€ 양을 μž‘μ•„μ„œ λ°°μ—΄μ˜ 증가에 μ˜ˆμƒν•œλ‹€. 그리고 곧 μžˆμ„ ν™•μž₯에 μ œκ³΅ν•  μ˜μ—­μ„ μ€λΉ„ν•΄ λ†“λŠ” 것이닀. μ˜ˆλΌ λ“€μ–΄ μš°λ¦¬λŠ” DynArray::operator[]λΌ μ΄λ ‡κ²Œ μ“Έμˆ˜ μžˆλ‹€.
~cpp 
    template<class T>
    T& DynArray<T>::operator[](int index)
    {
        if (index < 0) μ˜ˆμ™ΈλΌ λ˜μ§„λ‹€.;
        if (index > ν˜„μž¬ 인덱슀의 μ΅œλŒ€κ°’){
            int diff = index - ν˜„μž¬ 인덱슀의 μ΅œλŒ€κ°’;
            μ•Œλ§žμ€ λ©”λͺ¨λ¦¬λΌ ν• λ‹Ήν•œλ‹€. κ·Έλž˜μ„œ index+diffκ°€ μœ νš¨ν•˜κ²Œ ν•œλ‹€.
        }
        return ν˜„μž¬ μΈλ±μŠ€κ°€ κ°€λ¦¬ν‚€λŠ” 인자;
    }
이 ν•¨μˆ˜λŠ” λ‘λ²ˆ μΆ©λΆ„ν•œ μ–‘μ˜ 배열을 각각 ν•„μš”ν• λ•Œ ν• λ‹Ήν•œλ‹€. λ§Œμ•½ μš°λ¦¬κ°€ μ•žμ„œ μ΄μ•ΌκΈ°ν•œ μ“°μž„μ˜ μ‹œλ‚˜λ¦¬μ˜€λŒ€λ‘œ 진행 λœλ‹€λ©΄, μ•„λ§ˆ DynArrayλŠ” 그것이 λ‘λ²ˆμ˜ 논리적 크기의 ν™•μž₯을 할지라도 였직 λ©”λͺ¨λ¦¬λΌ ν•œλ²ˆλ§Œ ν• λ‹Ήν•  것이닀.:
~cpp 
DynArray<double> a;     // 였직 a[0]만이 μœ νš¨ν•˜λ‹€.
a[22] = 3.5;            // ν˜„μž¬ index 44μ •λ„μ˜ μ €μž₯ 곡간을 
                        // ν• λ‹Ήν•˜λ©° a의 논리적 곡간은 23이닀.
a[32] = 0;              // a의 논리적 곡간은 이제 a[32]이닀. ν•˜μ§€λ§Œ 
                        // 44의 μ €μž₯곡간이 μžˆκΈ°μ— ν™•μž₯ν•˜μ§€ μ•ŠλŠ”λ‹€.
λ§Œμ•½ λ‹€μ‹œ ν™•μž₯이 ν•„μš”ν•˜λ‹€λ©΄ 44보닀 크지 μ•ŠλŠ”λ‹€λ©΄, new에 μ˜ν•œ 높은 λΉ„μš©μ„ μΉ˜λ£¨μ§€ μ•ŠλŠ”λ‹€.

이번 μ•„μ΄ν…œμ€ 일반적인 μ‚¬μš©μ„ λ‹€λ£¨μ—ˆλ‹€. 그리고 속도 ν–₯상은 상응 ν•˜λŠ” λ©”λͺ¨λ¦¬ λΉ„μš©μ„ μ§€λΆˆμ„ ν•΄μ•Όλ§Œ ν• μˆ˜ μžˆλ‹€. μ΅œλŒ€κ°’, μ΅œμ†Œκ°’, 평균을 κ°μ•ˆν•΄μ„œ μš”κ΅¬λ˜λŠ” μ—¬λΆ„μ˜ 곡간을 μœ μ§€ν•œλ‹€. ν•˜μ§€λ§Œ 그것은 μ‹œκ°„μ„ μ ˆμ•½ν•œλ‹€. cach κ²°κ³ΌλŠ” μ€λ” λ§Žμ€ λ©”λͺ¨λ¦¬μ˜ 곡간을 μš”κ΅¬ν•˜μ§€λ§Œ λ‹€μ‹œ ν• λ‹Ήλ˜λŠ” λΆ€λΆ„μ˜ μ‹œκ°„κ³Ό λΉ„μš©μ„ μ„μ—¬μ„œ λΉ„μš©μ„ μ ˆμ•½ν•œλ‹€. λΈλ¦¬ 가지고 였고(prefetching)은 λΈλ¦¬ 가지고 와야 할것에 λŒ€ν•œ 곡간을 μš”κ΅¬ν•˜μ§€λ§Œ, 맀번 κ·Έ μžμ›μ— μ ‘κ·Όν•΄μ•Ό ν•˜λŠ” μ‹œκ°„μ„ μ„μ—¬μ€λ‹€. μ΄λŸ¬ν•œ 이야기(κ°œλ…)은 Computer Science(컴퓨터 κ³Όν•™)μ—μ„œ 였래된 이야기 이닀.:일반적으둜 μ‹œκ°„ μžμ›κ³Ό 곡간 μžμ›κ³Όμ˜ κ΅ν™˜(trade). (κ·Έλ ‡μ§€λ§Œ 항상 이런 것이 가상 λ©”λͺ¨λ¦¬μ™€ 캐쉬 νŽ˜μ΄μ§€μ— κ°μ²΄λΌ λ§Œλ“œλŠ”κ²ƒμ΄ 참은 μ•„λ‹ˆλ‹€. λ“œλ¬Έ κ²½μš°μ— μžˆμ–΄, 큰 객체의 λ§Œλ“œλŠ” 것은 λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄μ˜ μ„±λŠ₯(performance)을 ν–₯상 μ‹œν‚¬ 것이닀. μ™œλƒν•˜λ©΄ λ‹Ήμ‹ μ˜ ν™œμ„±ν™” μš”κ΅¬μ— λŒ€ν•œ ν™œλ™μ΄ μ¦κ°€ν•˜κ±°λ‚˜, λ‹Ήμ‹ μ˜ 캐쉬에 λŒ€ν•œ 접근이 μ„μ–΄ λ“€λ˜ ν˜Ήμ€ λ‘˜λ‹€ μΌλ•Œ 말이닀. 당신은 μ–΄λ–»κ²Œ κ·ΈλŸ¬ν•œ λ¬Έμ œλΌ ν•΄κ²°ν•  방법을 찾을 것인가? 상황을 μ κ²€ν•˜κ³  κΆλ¦¬ν•˜κ³  또 κΆλ¦¬ν•΄μ„œ κ·Έλ¬Έμ œλΌ ν•΄κ²°ν•˜λΌ(Item 16μ°Έκ³ ).)

이번 μ•„μ΄ν…œμ—μ„œμ˜ λ‚˜μ˜ μΆ©κ³ -cachingκ³Ό prefetching을 ν†΅ν•΄μ„œ over-eager의 μ „λž΅μœΌλ‘œ μ˜ˆμƒλ˜λŠ” κ°’λ“€μ˜ λΈλ¦¬ 계산 μ‹œν‚€λŠ”κ²ƒ-은 κ²°μ½” item 17의 lazy evaluation(λŠ¦μ€ 계산)κ³Ό λ°˜λŒ€μ˜ κ°œλ…μ΄ μ•„λ‹ˆλ‹€. lazy evaluation의 κΈ°μˆ μ€ 당신이 항상 ν•„μš”ν•˜κΈ° μ•Šμ€ μ–΄λ– ν•œ κ²°κ³Όμ—λŒ€ν•œ 연산을 λ°˜λ“œμ‹œ μˆ˜ν–‰ν•΄μ•Όλ§Œ ν• λ•Œ ν”„λ‘œκ·Έλž¨μ˜ νš¨μœ¨μ„±μ„ 높이기 μœ„ν•œ κΈ°μˆ μ΄λ‹€. over-eager evaluation은 당신이 거의 항상 ν•˜λŠ” κ³„μ‚°μ˜ κ²°κ³Ό 값이 ν•„μš”ν• λ•Œ ν”„λ‘œκ·Έλž¨μ˜ νš¨μœ¨μ„ λ†’μ—¬ μ„것이닀. μ–‘μͺ½ λͺ¨λ‘λ‹€ eager evaluation(μ¦‰μ‹œ 계산)의 run-of-the-mill(μ‹€ν–‰μ˜ λΉ„μš©) μ μš©μ— λΉ„ν•΄μ„œ μ‚¬μš©μ΄ 더 μ–΄λ ΅λ‹€. κ·Έλ ‡μ§€λ§Œ λ‘˜λ‹€ ν”„λ‘œκ·Έλž¨ λ§Žμ€ λ…Έλ ₯으둜 μ μš©ν•˜λ©΄ λšœλ ·ν•œ μ„±λŠ₯ 샹항을 보일수 μžˆλ‹€.

1.4. Item 19:Understand the orgin of temporary objects.

  • Item 19:μž„μ‹œ κ°μ²΄λ“€μ˜ 기본을 μ΄ν•΄ν•˜μž.

ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μž„μ‹œ 객체에 κ΄€ν•΄μ„œ 이야기 ν• λ•Œ 그것은 보톡 κ°„λ‹¨νžˆ temporaries(μž„μ‹œμΈμž, μ΄ν•˜ temporaries)둜 λΆˆλ¦°λ‹€. μ˜ˆλΌ λ“€μ–΄μ„œ swap 루틴을 보자
~cpp 
template<class T>
void swap(T& object1, T& object2)
{
    T temp = object;
    object1 = object2;
    object2 = temp;
}
자 μ—¬κΈ°μ„œ tempλΌ λ³΄ν†΅ "temporary" 라고 λΆ€λ₯Έλ‹€. κ·Έλ ‡μ§€λ§Œ C++에 κ΄€μ μ—μ„œλŠ” tempλŠ” λ°˜λ“œμ‹œ temporary라고 κ·œμ •μ§€μ„μˆ˜ μ—†λ‹€. 그것은 ν•¨μˆ˜λ‚΄μ— μ‘΄μž¬ν•˜λŠ” λ‹¨μˆœν•œ 지역 객체일 뿐이닀.

C++ λ‚΄μ—μ„œμ˜ μ§„μ§œ temporaryκ°μ²΄λŠ” 보이지 μ•ŠλŠ”λ‹€.-이게 무슨 μ†Œλ¦¬μΈκ³  ν•˜λ‹ˆ, μ†ŒμŠ€λ‚΄μ—μ„œλŠ” 보이지 μ•ŠλŠ”λ‹€λŠ” μ†Œλ¦¬λ‹€. temporary객체듀은 non-heap 객체둜 λ§Œλ“€μ–΄ μ§€μ§€λ§Œ 이름이 λΆ™μ§€λΌ μ•ŠλŠ”λ‹€. (DeleteMe μ‹œκ°„λ‚˜λ©΄ PLμ±…μ˜ λ‚΄μš© 보좩) 단지 이름 지어지지 μ•Šμ€(unnamed)κ°μ²΄λŠ” 보톡 두가지 κ²½μš°μ€‘μ— ν•˜λ‚˜λ‘œ 볼수 μžˆλŠ”λ°:λ¬΅μ‹œμ (implicit) ν˜•λ³€ν™˜μœΌλ‘œ ν•¨μˆ˜ν˜ΈμΆœμ—μ„œ 적용되고, μ„±κ³΅μ‹œμ— λ°˜ν™˜λ˜λŠ” 객체듀. μ™œ, 그리고 μ–΄λ–»κ²Œ μ΄λŸ¬ν•œ μž„μ‹œ 객체(temporary objects)κ°€ μƒμ„±λ˜κ³ , νŒŒκ΄΄λ˜μ–΄ μ§€λŠ”μ§€ μ΄ν•΄ν•˜λŠ” 것은 μ΄λŸ¬ν•œ 생성과 파괴 κ³Όμ •μ—μ„œ λ°œμƒν•˜λŠ” λΉ„μš©μ΄ λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ˜ μ„±λŠ₯에 μ–Όλ§ˆλ‚˜ μ„±λŠ₯을 끼칠수 μžˆλŠ”κ°€ μ•Œμ•„μ•Ό ν•˜κΈ°λ•Œλ¬Έμ— μ€‘μš”ν•œ 것이닀.

μž„μ‹œ 객체(temporary objects)κ°€ ν•¨μˆ˜ 호좜이 μ„±κ³΅λœν›„ λ§Œλ“€μ–΄μ§€λŠ” κ²½μš°λΌ μ²«λ²ˆμ§Έλ‘œ 생각해 보자. 이것은 ν•¨μˆ˜μ— μΈμžλΌ μ „λ‹¬ν• λ•Œ μ„œλ‘œκ°„μ— μΈμžλ“€μ˜ ν˜•(type)κ°€ λ§žμ§€ μ•Šκ²Œ λ¬Άμ—¬(bind)진 κ²½μš°μ— 일어 λ‚œλ‹€. μ˜ˆλΌ λ“€μžλ©΄, λ‹€μŒκ³Ό 같은 λ¬Έμžμ—΄μ—μ„œ μ–΄λŠ ν•œκΈ€μžκ°€ μΆœν˜„ν•˜λŠ” κ°μˆ˜λΌ μ„ΈλŠ” ν•¨μˆ˜λΌ μƒκ°ν•΄ 보자
~cpp 
    // λ‹€μŒ ν•¨μˆ˜λŠ” strμ•ˆμ—μ„œ chκ°€ λͺ‡κ²Œ μžˆλŠ”κ°€ λ°˜ν™˜ν•œλ‹€.
    size_t countChar(const string& str, char ch);
    char buffer[MAX_STRING_LEN];
    char c;
    // stringκ³Ό charλΌ λ°›μ•„ 듀인닀. setw λŠ” κΈ€μžλΌ μ½μ„λ•Œ 
    // μ˜€λ²„ ν”Œλ‘œμš°(overflow)λΌ λ°©μ§€ν•˜λŠ” λͺ©μ μœΌλ‘œ 쓰인닀.
    cin >> c >> setw(MAX_STRING_LEC) >> buffer;
    cout << "There are " << countChar(buffer, c)
         << " occurrences of the charcter " << c
         << " in " << buffer << endl;
countChar을 ν˜ΈμΆœν•˜λŠ” 곳을 보라. μ²˜μŒμ— κ΅¬λ¬Έμ—μ„œ char 배열이 ν•¨μˆ˜λ‘œ μ „λ‹¬λœλ‹€. ν•˜μ§€λ§Œ ν•¨μˆ˜μ˜ μΈμžλŠ” const string& 이닀. 이런 ν˜ΈμΆœμ€ 였직 ν˜•(type)이 μ•Œλ§žμ§€ μ•Šμ€κ²ƒμ΄ μ œκ±°λ˜κ±°λ‚˜ λ‹Ήμ‹ μ˜ μ»΄νŒŒμΌλŸ¬λŠ” ν›Œλ₯­νžˆλ„ string ν˜•μ˜ μž„μ‹œ 객체(temporary object)λΌ λ§Œλ“€μ–΄μ„œ κ·ΈλŸ¬ν•œ λ§žμ§€ μ•ŠλŠ” ν˜•λ¬Έμ œλΌ μ œκ°€ν•˜λ©΄ μ„±κ³΅ν• μˆ˜ μžˆλ‹€. κ·ΈλŸ¬ν•œ μž„μ‹œ κ°μ²΄λŠ” string μƒμ„±μžκ°€ bufferμΈμžλΌ λ°”νƒ•μœΌλ‘œ μ΄ˆκΈ°ν™” λœλ‹€. 그러면 constChar의 strμΈμžλŠ” μž„μ‹œ(temporary) string κ°μ²΄λΌ λ°›μ•„λ“€μΈλ‹€.(bind-bound) countChar이 λ°˜ν™˜λ λ•Œ μž„μ‹œ(temporary)κ°μ²΄λŠ” μžλ™ μ†Œλ©Έλœλ‹€.

μ΄λŸ¬ν•œ νŽΈν•œ(μœ„ν—˜ ν•˜μ§€λ§Œ-Item 5μ°Έκ³ )λ³€ν™˜(conversion) 은 ν•˜μ§€λ§Œ νš¨μœ¨μ„±μ˜ μΈ‘λ³€μ—μ„œ λ³Έλ‹€λ©΄, μž„μ‹œ string 객체의 생성과 νŒŒκ΄΄λŠ” λΆˆν•„μš”ν•œ λΉ„μš©μ΄λ‹€. 그것을 μ œκ±°ν•˜λŠ” κ²ƒμ—λŠ” λ‘κ°€μ§€μ˜ 일반적인 방법이 μžˆλŠ”λ°, ν•˜λ‚˜λŠ” λ‹Ήμ‹ μ˜ μ½”λ“œμ—μ„œ ν•΄λ‹Ή λ³€ν™˜μ„ μ—†μ•  λ²„λ¦¬λŠ” 것이닀. κ·Έ 방법은 Item 5에 κΈ°μˆ λ˜μ–΄ μžˆλ‹€. 또 ν•˜λ‚˜μ˜ 방법은 λ‹Ήμ‹ μ˜ μ†Œν”„νŠΈμ›¨μ–΄λΌ μˆ˜μ •ν•΄μ„œ λ³€ν™˜ μžμ²΄κ°€ ν•„μš”μ—†κ²Œ λ§Œλ“œλŠ” 방법이닀. 이것은 Item 21에 방법이 κΈ°μˆ λ˜μ–΄ μžˆλ‹€.

μ΄λŸ¬ν•œ λ³€ν™˜λ“€(conversions)은 였직 객체듀이 κ°’μœΌλ‘œ(by value)λ‚˜ μƒμˆ˜ μ°Έμ‘°(reference-to-const)둜 μ „λ‹¬λ λ•Œ μΌμ–΄λ‚œλ‹€. μƒμˆ˜ μ°Έμ‘°κ°€ μ•„λ‹Œ μ°Έμ‘°μ—μ„œλŠ”(reference-to-non-const) λ°œμƒν•˜μ§€ μ•ŠλŠ” λ¬Έμ œμ΄λ‹€. λ‹€μŒκ³Ό 같은 ν•¨μˆ˜μ— κ΄€ν•˜μ—¬ 생각해 보자:
~cpp 
    void uppercasify(string& str);      // str의 λͺ¨λ“  κΈ€μžλΌ λŒ€λ¬Έμžλ£Œ λ°”κΎΌλ‹€.
κΈ€μž μ„ΈκΈ°(charter-counting)μ˜ˆμ œμ—μ„œ char 배열은 μ„±κ³΅μ μœΌλ‘œ countChar둜 μ „λ‹¬λœλ‹€. κ·Έλ ‡μ§€λ§Œ 이것과 같은 ν•¨μˆ˜μ—μ„œλŠ” μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. λ‹€μŒκ³Ό 같은 μ½”λ“œ 말이닀.
~cpp 
    char subtleBookPlug[] = "Effective C++";
    uppercasify(subtleBookPlug);        // μ—λŸ¬λ‹€!
μ–΄λ– ν•œ μž„μ‹œμΈμž(temporary)도 λ§Œλ“€μ–΄ 지지 μ•Šμ•˜λ‹€. μ™œ λ§Œλ“€μ–΄ 지지 μ•Šμ€ 걸까?

μž„μ‹œμΈμž(temporary)κ°€ λ§Œλ“€μ–΄ μ‘Œλ‹€κ³  κ°€μ •ν•΄ 보자. μž„μ‹œμΈμžλŠ” uppercasify둜 μ „λ‹¬λ˜κ³  ν•΄λ‹Ή ν•¨μˆ˜λ‚΄μ—μ„œ λŒ€λ¬Έμž λ³€ν™˜ 과정을 κ±°μΉœλ‹€. ν•˜μ§€λ§Œ ν™œμ„±ν™”λœ, ν•„μš”ν•œ μžλ£Œκ°€ λ“€μ–΄μžˆλŠ” λΆ€λΆ„-subtleBookPlug-μ—λŠ” μ •μž‘ 영ν–₯을 λΌμΉ˜μ§€ λͺ»ν•œλ‹€.;였직 subtleBookPulgμ—μ„œ λ§Œλ“€μ–΄μ§„ μž„μ‹œ 객체인 string 객체만이 λ°”λ€Œμ—ˆλ˜ 것이닀. λ¬Όλ‘  이것은 ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ˜λ„ν–ˆλ˜ 봐도 μ•„λ‹ˆλ‹€. ν”„λ‘œκ·Έλž˜λ¨Έμ˜ μ˜λ„λŠ” subtleBookPlugκ°€ uppercasify에 영ν–₯을 λ°›κΈ°λΌ μ›ν•˜κ³ , ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” subtleBookPlugκ°€ μˆ˜μ •λ˜κΈ°λΌ λ°”λž¬λ˜ 것이닀. μƒμˆ˜ 객체의 μ°Έμ‘°κ°€ μ•„λ‹Œ 것(reference-to-non-const)에 λŒ€ν•œ μ•”μ‹œμ (implicit) ν˜•λ³€ν™˜μ€ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μž„μ‹œκ°€ μ•„λ‹Œ 객체듀에 λŒ€ν•œ λ³€ν™”λΌ μ˜ˆμΈ‘ν• λ•Œ μž„μ‹œ κ°μ²΄λ§Œμ„ λ³€κ²½ μ‹œν‚¨λ‹€. 그것이 μ–Έμ–΄μƒμ—μ„œ non-const reference μΈμžλ“€μ„ μœ„ν•˜μ—¬ μž„μ‹œλ¬Όλ“€(temporaries)의 생성을 λ§‰λŠ” μ΄μœ μ΄λ‹€. Reference-to-const μΈμžλŠ” 그런 λ¬Έμ œμ— λŒ€ν•œ 걱정이 μ—†λ‹€. μ™œλƒν•˜λ©΄ 그런 μΈμžλ“€μ€ const의 원리에 따라 λ³€ν™”λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.

μž„μ‹œκ°μ²΄κ°€ λ§Œλ“€μ–΄μ§€λŠ” λ‘λ²ˆμ§Έμ˜ 경우 그것은 λ°”λ‘œ ν•¨μˆ˜μ—μ„œ λ°˜ν™˜λ˜λŠ” μΈμžλ“€μ΄λ‹€. μ˜ˆλΌ λ“€μžλ©΄ operator+λŠ” λ°˜λ“œμ‹œ ν•΄λ‹Ή μΈμžλ“€μ˜ 합을 ν‘œν˜„ν•˜λŠ” κ°μ²΄λΌ λ°˜ν™˜ν•΄μ•Όλ§Œ ν•œλ‹€. 예λΌλ“€μ–΄μ„œ ν˜•μ΄ Number둜 μ£Όμ–΄μ‘Œλ‹€κ³  ν–ˆμ„λ•Œ operator+λŠ” λ‹€μŒκ³Ό 같이 μ„ μ–Έλœλ‹€.
~cpp 
const Number operator+(const Number& lhs, const Number &rhs);
ν•΄λ‹Ή ν•¨μˆ˜μ˜ λ°˜ν™˜ 인자(const Number)λŠ” μž„μ‹œλ¬Ό(temporary)이닀. μ™œλƒν•˜λ©΄ 그것은 μ•„λ¬΄λŸ° 이름도 가지기 μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.:단지 ν•¨μˆ˜μ˜ λ°˜ν™˜λ˜λŠ” 값일 뿐이닀. 당신은 λ°˜λ“œμ‹œ operator+κ°€ ν˜ΈμΆœλ λ•Œ ν•΄λ‹Ή 객체의 생성, μ‚­μ œμ— κ΄€ν•œ λΉ„μš©μ„ μ§€λΆˆν•΄μ•Όλ§Œ ν•œλ‹€. (λ°˜ν™˜ 값이 const인것에 κ΄€ν•œ μ΄μœ λΌ μ•Œκ³  μ‹Άλ‹€λ©΄ Item 6을 μ°Έκ³ ν•˜λΌ)

보톡 당신은 μ΄λŸ¬ν•œ λΉ„μš©μœΌλ‘œ ν”Όν•΄ μž…λŠ”κ±Έ μ›ν•˜μ§€ μ•ŠλŠ”λ‹€. 이런 νŠΉλ³„λ‚œ ν•¨μˆ˜μ— λŒ€ν•˜μ—¬ 당신은 μ•„λ§ˆ λΉ„μŠ·ν•œ ν•¨μˆ˜λ“€λ‘œ κ΅μ²΄ν•΄μ„œ λΉ„μš© μ§€λΆˆμ„ ν”Όν• μˆ˜ μžˆλ‹€.;Item 22λŠ” λ‹Ήμ‹ μ—κ²Œ μ΄λŸ¬ν•œ λ³€ν™˜μ— λŒ€ν•˜μ—¬ 말해 μ€λ‹€. ν•˜μ§€λ§Œ κ°μ²΄λΌ λ°˜ν™˜ν•˜λŠ” λŒ€λΆ€λΆ„μ˜ ν•¨μˆ˜λ“€μ€ μ΄λ ‡κ²Œ λ‹€λ₯Έ ν•¨μˆ˜λ‘œμ˜ λ³€ν™˜μ„ ν†΅ν•΄μ„œ 생성, μ‚­μ œμ— λŒ€ν•œ λΉ„μš© μ§€μΆœμ— λ¬Έμ œλΌ ν•΄κ²°ν•  방법이 μ—†λ‹€. μ΅œμ†Œν•œ 그것은 κ°œλ…μ μœΌλ‘œ ν”Όν• λ €κ³  ν•˜λŠ” 방법도 쑴재 ν•˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ κ°œλ…κ³Ό μ‹€μ œ(concep, reality)λŠ” μ΅œμ ν™”(optimization)이라 λΆˆλ¦¬λŠ” 어두 μ»΄μ»΄ν•œ μ• λ§€ν•œ 뢀뢄이닀. 그리고 λ•Œλ‘œ 당신은 λ‹Ήμ‹ μ˜ μ»΄νŒŒμΌλŸ¬μ—κ²Œ μž„μ‹œ 객체의 μ‘΄μž¬λΌ ν—ˆμš©ν•˜λŠ” λ°©λ²•μœΌλ‘œ λ‹Ήμ‹ μ˜ 객체λΌ-λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ“€μˆ˜ μžˆλ‹€. μ΄λŸ¬ν•œ μ΅œμ ν™”λ“€μ€ return value oprimization으둜 Item 20의 μ£Όμ œμ΄λ‹€.

μž„μ‹œ 객체의 λ°‘λ°”νƒ•μ˜ 생각은 λΉ„μš©μ΄ λ°œμƒν•˜λ‹€. 이닀. κ·Έλž˜μ„œ 당신은 κ°€λŠ₯ν•œν•œ 그것을 μ—†μ• κΈ°λΌ μ›ν•  것이닀. ν•˜μ§€λ§Œ 이보닀 더 μ€‘μš”ν•œ 것은, μ΄λŸ¬ν•œ μž„μ‹œ 객체의 λ°œμƒμ— 뢀뢄에 λŒ€ν•œ 톡찰λ ₯을 κΈ°λ₯΄λŠ” 것이닀. reference-to-const(μƒμˆ˜μ°Έμ‘°)λΌ μ‚¬μš©ν•œλ•ŒλŠ” μž„μ‹œ 객체가 인자둜 μ „λ‹¬λ μˆ˜ μžˆλŠ” κ°€λŠ₯성이 쑴재 ν•˜λŠ” 것이닀. 그리고 객체둜 ν•¨μˆ˜ 값을 λ°˜ν™˜ ν• λ•ŒλŠ” μž„μ‹œ 인자(temporary)λŠ” μ•„λ§ˆλ„ λ§Œλ“€μ–΄μ§ˆκ²ƒμ΄λ‹€.(그리고 νŒŒκ΄΄λ˜μ–΄ 진닀.) κ·ΈλŸ¬ν•œ 생성에 λŒ€ν•΄ μ˜ˆμΈ‘ν•˜κ³ , 당신이 "behind the scences"(보이지 μ•ŠλŠ” λΆ€λΆ„) μ—μ„œμ˜ μ»΄νŒŒμΌλŸ¬κ°€ μ§€λΆˆν•˜λŠ” λΉ„μš©μ— λŒ€ν•œ λˆˆμ„ λ°°μ›Œμ•Ό ν•œλ‹€.

1.5. Item 20: Facilitate the return value optimization

  • Item 20: λ°˜ν™˜λ˜λŠ” 값을 μ΅œμ ν™” ν•˜λΌ

κ°μ²΄λΌ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λŠ” 효율적으둜 λ§Œλ“œλŠ” λ…Έλ ₯을 νŒŒκ΄΄ν•œλ‹€.(DeleteMe μ•½κ°„ 이상) μ™œλƒν•˜λ©΄ κ°’μœΌλ‘œμ˜ λ°˜ν™˜(by-value) 같은 μƒμ„±μžμ™€ νŒŒκ΄΄μžκ°€ μ•”μ‹œμ μœΌλ‘œ ν˜ΈμΆœλ˜λŠ” 녀석을 ν¬ν•¨ν•˜λŠ” 것듀은 제거될수 μ—†κΈ° λ•Œλ¬Έμ΄λ‹€. 이 λ¬Έμ œλŠ” κ°„λ‹¨ν•˜λ‹€:μ •ν™•ν•œ λ°˜μ‘μ΄λ‚˜ 그렇지 μ•Šμ•˜λ‹€λŠ” 것을 μ•Œλ €μ£ΌλŠ” κ°μ²΄λΌ ν•¨μˆ˜κ°€ λ¦¬ν„΄ν•˜λŠ” 것이닀. λ§Œμ•½ κ·ΈλŸ¬ν•˜λ‹€λ©΄ λ°˜ν™˜λœ κ°μ²΄λΌ μ œκ±°ν•  방법은 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€.

μœ λ¦¬μˆ˜λΌ μœ„ν•œ operator* λΌ μƒκ°ν•΄ 보자
~cpp 
    class Rational {
    public:
        Rational(int numerator = 0, int denominator = 1);
        ...
        int numerator() const;
        int denominator() const;
    };

    // λ°˜ν™˜ 값이 μ™œ const μΈμ§€λŠ” Item 6을 μ°Έκ³ ν•˜λΌ
    const Rational operator* (const Rational& lhs, const Rational& rhs);
operator*λΌ μœ„ν•œ μ½”λ“œλΌ μ œμ™Έν•˜κ³ , μš°λ¦¬λŠ” λ°˜λ“œμ‹œ κ°μ²΄λΌ λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€λŠ”κ±Έ μ•Œκ³  μžˆλ‹€. μ™œλƒν•˜λ©΄ μœ λ¦¬μˆ˜κ°€ λ‘κ°œμ˜ μž„μ˜μ˜ 숫자둜 ν‘œν˜„λ˜κΈ° λ•Œλ¬Έμ΄λ‹€. 이것듀은 μž„μ˜μ˜ μˆ«μžμ΄λ‹€. μ–΄λ–»κ²Œ operator*κ°€ κ·Έκ²ƒλ“€μ˜ 곱을 μˆ˜ν–‰ν•˜κΈ°μœ„ν•œ μƒˆλ‘œμš΄ 객체의 생성을 ν”Όν• μˆ˜ μžˆμ„κΉŒ? ν• μˆ˜ μ—†λ‹€. κ·Έλž˜μ„œ μƒˆλ‘œμš΄ κ°μ²΄λΌ λ§Œλ“€κ³  그것을 λ°˜ν™˜ν•œλ‹€. κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³ , C++ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” κ°’μœΌλ‘œ λ°˜ν™˜μ‹œ(by-value)μ‹œ μΌμ–΄λ‚˜λŠ” λΉ„μš©μ˜ μ œκ±°λΌ μœ„ν•˜μ—¬ Herculean 의 λ…Έλ ₯으둜 μ‹œκ°„μ„ μ†ŒλΉ„ν•œλ‹€.

λ•Œλ‘œ μ‚¬λžŒλ“€μ€ μš°μŠ΅κ²Œλ„ μ΄λŸ¬ν•œ λ¬Έλ²•μœΌλ‘œ ν¬μΈν„°λΌ λ°˜ν™˜ν•œλ‹€.
~cpp 
    // μ΄λŸ¬ν•œ 객체의 λ°˜ν™˜μ€ ν”Όν•΄μ•Όν•  방법이닀.
    const Rational* operator* (const Rational& lhs, const Rational& rhs);
    const Rational a = 10;
    Rational b(1,2);
    Rational c = *(a * b);    // 이것이 "μžμ—°μŠ€λŸ¬μš΄" κ²ƒμΌκΉŒ?
그것은 λ˜ν•œ μ˜λ¬Έμ„ μžμ•„ λ‚Έλ‹€. ν˜ΈμΆœμžκ°€ ν•¨μˆ˜μ— μ˜ν•΄ λ°˜ν™˜λœ ν¬μΈν„°λΌ λ°”νƒ•μœΌλ‘œ κ°μ²΄λΌ μ œκ±° ν•΄μ•Ό ν•˜λŠ”κ±°? μ΄λŸ¬ν•œ λŒ€λ‹΅μ— κ΄€ν•΄μ„œ 보톡은 "λ„€" 이고 보톡은 μžμ›μ΄ μƒˆμ–΄λ‚˜κ°€λŠ”(Resource leak)것을 λ°œμƒ μ‹œν‚¨λ‹€.

λ‹€λ₯Έ κ°œλ°œμžλ“€μ€ μ°Έμ‘°(reference)둜 λ°˜ν™˜ν•œλ‹€. λ¬Όλ‘ , 그것은 λ¬Έλ²•μ μœΌλ‘œλŠ” μˆ˜μš©ν• μˆ˜ μžˆλ‹€.
~cpp 
    // 객체의 λ°˜ν™˜μ„ ν”Όν•˜κΈ°μ—λŠ” μœ„ν—˜ν•˜κ³  μ˜³λ°”λ₯΄μ§€ μ•Šμ€ 방법이닀.
    const Rational& operator* (const Rational& lhs, const Rational& rhs);
    const Rational a = 10;
    Rational b(1,2);
    Rational c = a * b;    // λ³΄κΈ°μ—λŠ” μ™„μ „ν•΄ 보인닀.
κ·Έλ ‡μ§€λ§Œ μ΄λŸ¬ν•œ ν•¨μˆ˜λŠ” κ²°μ½” μ •ν™•ν•œ 행동을 μœ„ν•΄μ„œ μ½”λ“œμ— μ μš©ν•˜μ§€ λͺ»ν•œλ‹€. 보톡 μ΄λ ‡κ²Œ μ§œμ—¬ μ§ˆν…λ°,
~cpp 
    // κ°μ²΄λΌ λ°˜ν™˜ν•˜λŠ” 또 λ‹€λ₯Έ λ©μ²­ν•˜κ³  μœ„ν—˜ν•œ 방법이닀.
    const Rational& operator*(const Rational& lhs, const Rational& rhs)
    {
        Rational result(lhs.numerator() * rhs.numerator(), lhs.denominator(), rhs.denominator());
        return result;
    }
이 ν•¨μˆ˜λŠ” 더이상 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μ°Έμ‘°λΌ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€. 그것이 λ°˜ν™˜ν•˜λŠ” κ°μ²΄λŠ” 지역 객체인 result이며 이 resultλŠ” ν•¨μˆ˜μΈ operator*κ°€ μ’…λ£Œλ˜λ©΄ μžλ™μœΌλ‘œ μ‚­μ œλœλ‹€. κ·Έλž˜μ„œ λ°˜ν™˜λœ νŒŒκ΄΄λ˜μ–΄μ§„ ν•΄λ‹Ή 객체의 μ°Έμ‘° 값은 μ“Έμˆ˜ μ—†λ‹€.

이것에 κ΄€ν•΄μ„œ λ‚˜λΌ λΏμ–΄λΌ:λͺ‡λͺ‡ ν•¨μˆ˜λ“€(operator*κ°€ 그쀑이닀.)λŠ” κ²°κ΅­ κ°μ²΄λΌ λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€λŠ” 것. 그것이 방법이고 이것에 λŒ€ν•˜μ—¬ μ™ˆκ°€μ™ˆλΆ€ ν•˜μ§€λ§ˆλΌ 당신은 이길수 μ—†λ‹€.

당신이 κ°’μœΌλ‘œ(by-value)의 전달을 μ•ˆμ“°κ³  λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ ν•˜λ €λŠ” μ‹œλ„λŠ” κ²°μ½” 이길수 μ—†λ‹€. ν•˜μ§€λ§Œ 이런 잘λͺ»λœ μ‹Έμ›€μ—μ„œλ„ μ–»λŠ”κ²ƒμ€ μžˆλ‹€. 효율의 κ΄€μ μ—μ„œ λ³Έλ‹€λ©΄, 당신은 κ°μ²΄λΌ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ— κ΄€ν•΄ 신경쓰지 말아야 ν•œλ‹€, 당신은 였직 객체의 λΉ„μš©μ— κ΄€ν•΄μ„œλ§Œ μ‹ κ²½ 써야 ν•œλ‹€. λ‹Ήμ‹ μ˜ λ…Έλ ₯을 λ°˜ν™˜ 객체에 λŒ€ν•œ λΉ„μš©μ„ μ„μ΄λŠ”λ°λ§Œ μ‹ κ²½ μ“°κ³ , κ·Έκ²ƒλ“€μ˜ μ œκ±°μ— κ΄€ν•΄μ„œλŠ” 신경을 끊기 μœ„ν•΄μ„œλŠ” 무엇이 ν•„μš”ν• κΉŒ? λ§Œμ•½ μ΄λŸ¬ν•œ 객체듀에 κ΄€ν•΄μ„œ μ•„λ¬΄λŸ° λΉ„μš©μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.λ©΄ λˆ„κ°€ 이런 κ°μˆ˜μ— κ΄€ν•΄μ„œ μ‹ κ²½ μ“ΈκΉŒ?

μ»΄νŒŒμΌλŸ¬κ°€ μž„μ‹œ μΈμžλ“€μ— λŒ€ν•œ λΉ„μš© 을 μ œκ±°ν• μˆ˜ μžˆλŠ” 그런 방법이라면, κ°μ²΄λΌ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜ μž‘μ„±μ— λŒ€ν•΄μ„œλŠ” κ°€λŠ₯ν•  것이닀. λ§Œμ•½ 객체 λŒ€μ‹ μ— μƒμ„±μž ꡬ문을 μ¨λ„£μ–΄λ²„λ¦¬λŠ” 트릭(trick)이라면 말이닀. 그리고 λ‹€μŒκ³Ό 같이 ν• μˆ˜ μžˆλ‹€.
~cpp 
// κ°μ²΄λΌ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ— κ΄€ν•˜μ—¬ 효율적이고 μ •ν™•ν•œ μ μš©μ„ μœ„ν•΄ λ‹€μŒκ³Ό 같이 ν•œλ‹€.
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
    return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator());
}
λ°˜ν™˜λ˜λŠ” ν‘œν˜„μ‹μ„ μžμ„Ένžˆ μ‚΄νŽ΄ 봐라. 그것은 Raional의 μƒμ„±μžμ΄λ‹€. 당신은 μž„μ‹œ 객체 RationalλΌ λ‹€μŒ ν‘œν˜„μ—μ„œ λ§Œλ“€μ–΄ λ‚΄λŠ” 것이닀.
~cpp 
    Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator());
그리고 이 μž„μ‹œ κ°μ²΄λŠ” ν•¨μˆ˜κ°€ λ°˜ν™˜ 값을 μœ„ν•˜μ—¬ λ³΅μ‚¬ν•œλ‹€.

μ΄λŸ¬ν•œ 지역 객체 λŒ€μ‹ μ˜ μƒμ„±μž ꡬ문을 λ°˜ν™˜ν•˜λŠ” μž‘μ—…μ€ λ‹Ήμ‹ μ—κ²Œ 더 λ§Žμ€κ±Έ μš”κ΅¬ν•œλ‹€. μ™œλƒν•˜λ©΄ 당신은 아직 μž„μ‹œ 객체에 λŒ€ν•œ 생성과 νŒŒκ΄΄μ— λŒ€ν•œ λΉ„μš©μ„ 가지고 있고, 당신은 ν•¨μˆ˜μ˜ λ°˜ν™˜ κ°μ²΄λ“€μ˜ 생성, νŒŒκ΄΄μ— λŒ€ν•œ λΉ„μš©μ„ μ§€λΆˆν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. κ·Έλ ‡μ§€λ§Œ 당신은 λͺ‡κ°€μ§€λΌ μ–»μ„μˆ˜ μžˆλ‹€. C++의 κ·œμΉ™μ€ μ»΄νŒŒμΌλŸ¬λ“€μ΄ μž„μ‹œ κ°μ²΄λΌ μ΅œμ ν™” μ‹œν‚€λ„λ‘ ν•œλ‹€. 결둠적으둜, λ§Œμ•½ 당신이 operator*의 ꡬ문이 이것고 κ°™λ‹€λ©΄,
~cpp 
    Rational a = 10;
    Rational b(1,2);
    Rational c = a * b;
λ‹Ήμ‹ μ˜ μ»΄νŒŒμΌλŸ¬λŠ” operator*λ‚΄λΆ€μ˜ μž„μ‹œ μΈμžλΌ μ—†μ• κ³  κ·Έ μž„μ‹œ μΈμžλŠ” operator*에 μ˜ν•˜μ—¬ λ°˜ν™˜ λœλ‹€. 그듀은 객체 cλΌ λ©”λͺ¨λ¦¬μ— ν• λ‹Ήν•˜λŠ” μ½”λ“œμ— λŒ€ν•˜μ—¬ return ν‘œν˜„μ— μ˜ν•΄ μ •μ˜λœ κ°μ²΄λΌ μƒμ„±ν•œλ‹€. λ§Œμ•½ λ‹Ήμ‹ μ˜ μ»΄νŒŒμΌλŸ¬κ°€ μ΄λ ‡κ²Œ ν•œλ‹€λ©΄ operator*에 λŒ€ν•œ μž„μ‹œ 객체의 총 λΉ„μš©μ€ zeroκ°€ λœλ‹€. κ²Œλ‹€κ°€ 당신은 이것보닀 더 쒋은 μ–΄λ– ν•œκ²ƒμ„ μƒκ°ν• μˆ˜ 없을꺼닀. μ™œλƒν•˜λƒλ©΄ cκ°€ 이름 지어진 객체이고, 이름 지어진 κ°μ²΄λŠ” 사라지지 μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.(Item 22μ°Έκ³ ). 거기에 당신은 inlineν•¨μˆ˜μ˜ μ„ μ–ΈμœΌλ‘œ operator*λΌ λΆ€λ₯΄λŠ” λΆ€ν•˜ κΉŒμ§€ μ—†μ•¨μˆ˜ μžˆλ‹€.
~cpp 
    inline const Rational operator* (const Rational& lhs, const Rational& rhs)
    {
        return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator());
    }
"λ‚΄~ λ‚΄" ν•˜κ³ μ„œ 당신은 κΆμ‹œλ  거릴꺼닀. "μ΅œμ ν™”λΌ..바보 짓이지. λˆ„κ°€ μ»΄νŒŒμΌλŸ¬κ°€ κ·Έλ ‡κ²Œ ν• μˆ˜ μžˆλ‹€κ³  ν•˜λŠ”κ±°μ§€? λ‚˜λŠ” 정말 μ»΄νŒŒμΌλŸ¬κ°€ μ €λ ‡κ²Œ ν•˜λŠ”μ§€ μ•Œκ³  싢은데. μ§„μ§œ μ»΄νŒŒμΌλŸ¬κ°€ μ €λŸ° 일을 ν•˜λŠ”κ±° λ§žμ•„?" μ΄λ ‡κ²Œ 말이닀. μ΄λŸ¬ν•œ νŠΉλ³„ν•œ μ΅œμ ν™”-ν•¨μˆ˜μ˜ λ°˜ν™˜ 값을 κ°€λŠ₯ν•œν•œ 지역 μž„μ‹œ 객체가 μ‚¬μš©λ˜λŠ” 것을 μ œκ±°ν•΄ λ²„λ¦¬λŠ”κ²ƒ-λŠ” 유λͺ…ν•œ 것이고, 일반적으둜 κ΅¬ν˜„λ˜μ–΄ μžˆλ‹€. 그것은 μ΄λ ‡κ²Œ 이름 뢙여진닀.:thr return value optimization. 사싀 이런 μ΅œμ ν™”μ— λŒ€ν•œ 이름은 μ•„λ§ˆ λ§Žμ€ κ³³μ—μ„œ μ„λͺ…λ˜μ–΄ μ§ˆκΊΌλ‹€. ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” C++μ»΄νŒŒμΌλŸ¬κ°€ "return value optimization"을 ν• μˆ˜ μžˆλŠ”μ§€ λ²€λ”λ“€μ—κ²Œ λ¬Όμ–΄ λ³Όμˆ˜λ„ μžˆμ„ 정도닀 λ§Œμ•½ ν•œ 벀더가 "예"라고 ν•˜κ³  λ‹€λ₯Έ 곳은 "λ­μš”?" 라고 λ¬»λŠ”λ‹€λ©΄ 첫번째 λ²€λ”λŠ” λ‹Ήκ·Ό 경쟁λ ₯μ—μ„œ μ•žμ„œ κ°€λŠ”κ±°λ‹€. μ•„~ 자본주의 인가. λ•Œλ‘  당신은 κ·Έκ±Έ μ’‹μ•„ ν• κΊΌλ‹€.

1.6. Item 21: Overload to avoid implicit type conversions.

  • Item 21: μ•”μ‹œμ (implicit) ν˜•λ³€ν™˜μ˜ overloadλΌ ν”Όν•˜λΌ

μ—¬κΈ° λͺ‡κ°œμ˜ λ³„λ‘œ 쒋지 μ•Šμ€ μ½”λ“œλ“€μ΄ μžˆλ‹€.

~cpp 
    class UPInt {
    public:
        UPInt();
        UPInt(int value);
        ...
    };
    const UPInt operator+( const UPInt& lhs, const UPInt& rhs);

    UPInt upi1, upi2;
    ...
    UPInt upi3 = upi1 + upi2;
뭐 λ†€λž„κ±΄ μ—†λ‹€. upi1κ³Ό upi2 λͺ¨λ‘ UPInt 객체이고, λ‘˜λ‹€ UPIntsλΌ μœ„ν•œ operator+에 μ˜ν•˜μ—¬ 더해진거닀.

μ—¬κΈ° κ΄€λ ¨ ꡬ뢄이닀.

~cpp 
    upi3 = upi1 + 10;
    upi3 = 10 + upi2;
이런 ꡬ문 μ—­μ‹œ μ„±κ³΅ν•œλ‹€. 그것듀은 μ •μˆ˜ 10을 UPInts둜 μž„μ‹œκ°μ²΄κ°€ μƒμ„±μœΌλ‘œ 일련의 과정을 μˆ˜ν–‰ν• μˆ˜ μžˆλ‹€.(Item 19μ°Έκ³ )

μ»΄νŒŒμΌλŸ¬κ°€ μˆ˜ν–‰ν•΄μ£ΌλŠ” 이런 μ’…λ₯˜μ˜ λ³€ν™˜μ€ μ°Έ νŽΈν•˜λ‹€. κ·Έλ ‡μ§€λ§Œ 이런 λ³€ν™˜μ— μ˜ν•΄ μƒμ„±λ˜λŠ” μž„μ‹œ κ°μ²΄λŠ” μš°λ¦¬κ°€ 바라지 μ˜ˆμƒν•˜μ§€ μ•Šμ€ λΉ„μš©μ„ λ°œμƒμ‹œν‚¨λ‹€. λ§Žμ€ μ‚¬λžŒλ“€μ€ 단지, μ΄λŸ¬ν•œ μž‘μ—…μ— λŒ€ν•˜μ—¬ μ•„λ¬΄λŸ° λΉ„μš©μ„ μ§€λΆˆν•˜μ§€ μ•ŠκΈ°λΌ λ°”λΌλŠ”κ²ƒ 처럼 λŒ€λ‹€μˆ˜ C++ ν”„λ‘œκ·Έλž˜λ¨Έλ“€λ„ μ•”μ‹œμ  ν˜•λ³€ν™˜μ΄ λΉ„μš©μ— μ•„λ¬΄λŸ° 영ν–₯을 λΌμΉ˜μ§€ μ•ŠκΈ°λΌ μ›ν•œλ‹€. κ·Έλ ‡μ§€λ§Œ 이런 계산없이 κ³Όμ—° μ–΄λ–»κ²Œ μˆ˜ν–‰ν• μˆ˜ μžˆμ„κΉŒ?

ν•œκ±ΈμŒ λ’€λ‘œ λ¬ΌλŸ¬μ„œμ„œ, 우리의 λͺ©ν‘œλŠ” ν˜•λ³€ν™˜ 이 μ•„λ‹Œ operator+λΌ UPInt와 intκ΅¬λΆ„μ˜ ν˜Όν•©μœΌλ‘œ ν˜ΈμΆœν• μˆ˜ 있게 λ§Œλ“€μˆ˜ μžˆμŒμ„ μ•Œμˆ˜ μžˆλ‹€. μ•”μ‹œμ  ν˜•λ³€ν™˜μ˜ λ¬Έμ œκ°€ 끝났것 κ°™λ‹€. 그러면, ν˜Όλž€μŠ€λŸ° 의λΈμ— μ’…μ§€λΆ€λΌ μ°μ–΄ 보자. μ—¬κΈ° operator+의 μˆ˜ν–‰μ„ μ„±κ³΅μ‹œν‚€λŠ” 또 λ‹€λ₯Έ ν˜Όν•©λœ(mixed-type) 호좜 방식이 μžˆλ‹€. 그것은 처음 μ‹œλ„ν•œ λ°©λ²•μ—μ„œ μ•”μ‹œμ  ν˜•λ³€ν™˜μ„ μ œκ±°ν•΄ μ„것이닀. λ§Œμ•½ μš°λ¦¬κ°€ UPInt와 intλΌ ν•©μ„ ν• μˆ˜ μžˆκΈ°λΌ μ›ν•œλ‹€λ©΄ μš°λ¦¬λŠ” κ·Έκ±Έ μ „λΆ€λ‹€ κ·Έλ ‡κ²Œ κ·ΈλŒ€λ‘œ λ§Œλ“ λ‹€. λͺ‡κ°œμ˜ ν•¨μˆ˜λΌ κ°κΈ° λ‹€λ₯Έ 인자 ν˜•(parameter type)으둜 overloadν•΄μ„œ μ„ μ–Έν•΄ λ²„λ¦¬λŠ” 것이닀.

~cpp 
    const UPInt operator+(const UPInt& lhs, const UPInt& rhs);
    const UPInt operator+(const UPInt& lhs, const int rhs);
    const UPInt operator+(const int lhs, const UPInt& rhs);

    UPInt upi1, upi2;
    ...
    UPInt upi3 = upi1 + upi2;
    upi3 = upi1 + 10;
    upi3 = 10 + upi1;
μš°λ¦¬λŠ” ν˜•λ³€ν™˜μ„ μ œκ±°ν•˜κΈ° μœ„ν•˜μ—¬ overloadλΌ ν•˜μ˜€λ‹€. ν•˜μ§€λ§Œ λ‹€μŒκ³Ό 같은 경우 λ¬Έμ œκ°€ λ°œμƒν• μˆ˜ μžˆλ‹€

~cpp 
    const UPInt operator+(const int lhs, const int rhs);
자 이제 잘 생각해 보자. UPInt와 int의 ν˜•μ„ μœ„ν•΄μ„œ μš°λ¦¬λŠ” λͺ¨λ“  κ°€λŠ₯ν•œ μΈμžλ“€μ„ operator+에 κ΅¬ν˜„ν•˜κΈ°λΌ μ›ν•œλ‹€. μ € μœ„μ˜ 예제의 μ„Έκ°€μ§€μ˜ overloading은 잘 μˆ˜ν–‰λ˜μ§€λ§Œ μ–‘ μΈμžκ°€ λͺ¨λ‘ int인 κ²½μš°μ—λŠ” λ˜μ§€ μ•ŠλŠλ‹€. μš°λ¦¬λŠ” μ΄κ²ƒλ§ˆμ Έ μˆ˜ν–‰ν• μˆ˜ μžˆκΈ°λΌ λ°”λž€λ‹€.

μ΄μ„±μ μ΄κ±°λ‚˜, μ•„λ‹ˆκ±°λ‚˜, 이 C++ game의 λ²•μΉ™μ—μ„œ λͺ¨λ“  overloadν•œ operatorλŠ” λ°˜λ“œμ‹œ μ‚¬μš©μž μ •μ˜ ν˜•(user-defined type)을 가지고 μžˆμ–΄μ•Ό ν•œλ‹€. κ·Έλž˜μ„œ μš°λ¦¬λŠ” μœ„μ™€ 같은 ꡬ문으둜 overloadν• μˆ˜ μ—†λŠ” 것이닀.(λ§Œμ•½ 이런 κ·œμΉ™μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄, ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” λΈλ¦¬ μ •μ˜λœ ν™•μ‹€ν•œ 의λΈλ“€μ˜ μ •μ˜λΌ ν•΄μΉ μˆ˜ μžˆλ‹€. μ˜ˆλΌ λ“€μ–΄ μœ„μ™€ 같은 intλ‘˜μ— λŒ€ν•΄ operator+λΌ overloadκ°€ κ°€λŠ₯ν•˜λ‹€λ©΄ int의 ν•©μ—λŒ€ν•œ κΈ°λ³Έ 의λΈκ°€ 변화할것이닀. 그것을 정말 μ›ν•˜λŠ” μ‚¬λžŒμ΄ μžˆμ„κΉŒ?)

μž„μ‹œκ°μ²΄μ˜ μ‚¬μš©μ„ ν”Όν•˜κΈ° μœ„ν•œ operator ν•¨μˆ˜μ— λŒ€ν•œ overloading은 νŠΉλ³„νžˆ μ œν•œλ˜λŠ” 것은 μ—†λ‹€. 예λΌλ“€μ–΄μ„œ λ§Žμ€ ν”„λ‘œκ·Έλž¨μ—μ„œ 당신은 string객체가 char*λΌ μˆ˜μš©ν•˜κΈ°λΌ λ°”λž„κ²ƒμ΄λ‹€. ν˜Ήμ€ κ·Έ λ°˜λŒ€μ˜ κ²½μš°μ—λ„ λ§ˆμ°¬κ°€μ§€μ΄λ‹€. λΉ„μŠ·ν•˜κ²Œ λ§Œμ•½ 당신이 complex(Item 35μ°Έκ³ )와 같은 수치 계산을 μœ„ν•œ κ°μ²΄λΌ μ‚¬μš©ν• λ•Œ 당신은 int와 double같은 νƒ€μž…λ“€μ΄ 수치 μ—°μ‚° 객체의 μ–΄λŠ κ³³μ—μ„œλ‚˜ 유용히 μ“°κΈ°λΌ μ›ν•  것이닀. 결과적으둜 string, char*, complex etc μ΄λŸ¬ν•œ νƒ€μž…λ“€μ„ μ‚¬μš©ν•˜λŠ”λ° μž„μ‹œ 인자의 제거 ν• λ €λ©΄ λͺ¨λ‘ overload된 ν•¨μˆ˜κ°€ μ§€μ›λ˜μ–΄μ•Ό ν•œλ‹€λŠ” 것이닀.

아직, 80-20 κ·œμΉ™(Item 16μ°Έκ³ )은 λ§ˆμŒμ†μ— μ€‘μš”ν•˜κ²Œ λ‚¨μ•„μžˆκ² μ§€. λ§Œμ•½ 당신이 κ·ΈλŸ¬γ…Žκ²ƒλ“€μ„ ν”„λ‘œκ·Έλž¨μ— μ΄μš©ν–ˆμ„λ•Œ λˆˆμ—λ λŠ” μ„±λŠ₯ ν–₯상을 보이지 μ•ŠλŠ” 쒋은 생각을 가지고 μžˆλ‹€λ©΄, overload된 ν•œμˆ˜λ“€μ˜ μ œκ±°μ— λŒ€ν•œ μ΄μ•ΌκΈ°λŠ” κ²°μ½” λ…Όμ˜μ˜ 촛점이 λ˜μ§€ μ•Šμ„ κΊΌλ‹€.

1.7. Item 22: Consider using op= instead of stand-alone op.

  • Item 22: 혼자 μ“°μ΄λŠ” op(+,-,/) λŒ€μ‹ μ— op=(+=,-=,/=)을 μ“°λŠ”κ±Έ 생각해 봐라.

λŒ€λ‹€μˆ˜ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ λ‹€μŒμ˜ κ²°κ³Όκ°€

~cpp 
    x = x + y;      x = x - y;
이 것과 λΉ„μŠ·ν•œ λ™μž‘μ„ 할것이라 λ§ν• μˆ˜ μžˆλ‹€.

~cpp 
    x += y;         x -= y;
λ§Œμ•½ x와 yκ°€ μ‚¬μš©μž μ •μ˜(user-defined)ν˜•μΌλ•Œ μ΄λŸ¬ν•œ 보증을 ν• μˆ˜ μžˆμ„κΉŒ? C++에 κ΄€ν•΄ 잘 생각해 보면 operator+, operator= λ‘˜κ³Ό operator+= λŠ” ν•˜λ“± 상관 μ—†λŠ”κ±°λ‹€. κ·Έλž˜μ„œ λ§Œμ•½μ— 당신이 μ„Έκ³„μ˜ operator듀이 μ„œλ‘œ 관계가 μžˆκΈ°λΌ μ›ν•œλ‹€λ©΄ λ‹Ήμ‹  슀슀둜 그것을 μ μš©ν•΄ μ£Όμ–΄μ•Ό ν•œλ‹€. λ§ˆμ°¬κ°€μ§€λ‘œ operator -, *, / λ“± μ „λΆ€λ‹€λ‹€.

쒋은 방법은 각 operator와 stand-alone version간에 μžμ—°μŠ€λŸ¬μš΄ κ΄€κ³„λΌ μƒκ°ν•΄μ„œ κ΅¬ν˜„ν•΄ μ£ΌλŠ” 것이닀. 이것은 μœ„μš΄ μ˜ˆμ΄λ‹€.

~cpp 
    class Rational{
    public:
        ...
        Rational& operator+=(const Rational& rhs);
        Rational& operator-=(const Rational& rhs);
    };
    // κ°’μœΌλ‘œμ˜ λ°˜ν™˜μ˜ μ΄μœ λŠ” Item 6μ°Έκ³ , const의 μ΄μœ λŠ” p109μ°Έκ³ 
    const Rational operator+(const Rational& lhs, const Rational& rhs)
    {
        return Rational(lhs) += rhs;
    }
    const Rational operator-(const Rational& lhs, const Rational& rhs)
    {
        return Rational(lhs) -= rhs;
    }
이 μ˜ˆμ œλŠ” operator+=κ³Ό operator-=이 λ‹€λ₯Έκ³³μ— κ΅¬ν˜„λ˜μ–΄ μžˆλŠ” 것이고, operator+와 operator-κ°€ 이듀을 μ΄μš©ν•΄ 각기 κΈ°λŠ₯을 κ΅¬ν˜„ν•œ λͺ¨μŠ΅μ΄λ‹€. 이런 λ””μžμΈμ΄λΌλ©΄, 이 operatorλ“€μ—κ²Œ ν• λ‹Ήλœ κΈ°λŠ₯은 μœ μ§€λ κ²ƒμ΄λ‹€.(λ‹€λ₯Έ 것이 λ³€ν•˜λ©΄ 같이 λ³€ν•œλ‹€λŠ” μ†Œλ¦¬) κ²Œλ‹€κ°€ public μΈν„°νŽ˜μ΄μŠ€μ—μ„œ operator듀이 ν• λ‹Ήλœ λ²„μ „μ—μ„œ 클래슀 μƒμ—μ„œ friendλ‘œμ„œ stand-alone operator에 λŒ€ν•œ ν•„μš”μ„±μ€ μ—†λ‹€.

λ§Œμ•½ 당신이 λͺ¨λ“  μ „μ—­ κ³΅κ°„μ•ˆμ— μžˆλŠ” stand-alone operator듀에 κ΄€ν•˜μ—¬ λ§ˆμŒμ„ λ†“μΉ˜ λͺ»ν•œλ‹€λ©΄, λ‹€μŒκ³Ό 같은 template을 μ‚¬μš©ν•΄μ„œ stand-alone ν•¨μˆ˜λ“€μ˜ μ‚¬μš©μ„ μ œκ±°ν• μˆ˜ μžˆλ‹€.:

~cpp 
    template<class T>
    const T operator+(const T& lhs, const T&rhs)
    {
        return T(lhs) += rhs;
    }
    template<class T>
    const T opreator-(const T& lhs, const T& rhs)
    {
        return T(lhs) -= rhs;
    }
    ...
λ‹€μŒκ³Ό 같은 ν…œν”Œλ¦Ώμ˜ μ‚¬μš©μœΌλ‘œ operator ν• λ‹Ή 버전이 μ–΄λ– ν•œ ν˜• T둜 μ •μ˜λ˜μ–΄μ Έ μžˆλŠ” μƒνƒœλΌλ©΄ stand-alone operatorλŠ” μ•„λ§ˆλ„ μžλ™μ μœΌλ‘œ 그것을 μƒμ„±ν•˜κ²Œ 될것이닀.

μ΄λŸ°κ²ƒμ€ μ°Έ 쒋은 방법이닀. ν•˜μ§€λ§Œ μš°λ¦¬λŠ” νš¨μœ¨μ— κ΄€μ μ—μ„œ 생각해 λ³Έλ‹€λ©΄ μ‹€νŒ¨ν–ˆμŒμ„ μ•Œμˆ˜ μžˆλ‹€. 이 μ±•ν„°μ˜ μ£Όμ œλŠ” νš¨μœ¨μ΄λ‹€. μ„Έκ°€μ§€μ˜ 효율의 κ΄€μ μ—μ„œ μΆ©λΆ„νžˆ μ΄λŸ°κ²ƒλ“€μ€ 쒋지 λͺ»ν•˜λ‹€.첫번째둜 보톡 operatorν• λ‹Ή 버전은 stnad-alone 버전에 λΉ„ν•˜μ—¬ 효율이 μ’‹λ‹€. μ™œλƒν•˜λ©΄ stand-alone 버전은 λ°˜λ“œμ‹œ μƒˆλ‘œμš΄ κ°μ²΄λΌ λ°˜ν™˜ν•˜κ³ , 그것은 μš°λ¦¬μ—κ²Œ μž„μ‹œ 객체의 생성과 파괴의 λΉ„μš©μ„ μ•ΌκΈ°ν•œλ‹€.(Item 19, 20μ°Έκ³ ) operator ν• λ‹Ή 버전은 κ·Έλ“€μ˜ μ™Όμͺ½ μΈμžλΌ κΈ°λ‘ν•œλ‹€ κ·Έλž˜μ„œ ν•΄λ‹Ή operator의 객체 λ°˜ν™˜μ‹œμ— μ•„λ¬΄λŸ° μž„μ‹œ μΈμžλΌ μƒμ„±ν•  ν•„μš”κ°€ μ—†λ‹€.

λ‘λ²ˆμ§Έλ‘œ μ€‘μš”ν•œ 점은 operator ν• λ‹Ή 버전은 stand-alone 버전 만큼 μ œκ³΅ν•˜λŠ” 것은, λ‹Ήμ‹ μ˜ ν΄λž˜μŠ€λΌ μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈλ“€μ—κ²Œ 효율과 νŽΈμ΄μ„± 이 λ‘λ§ˆλ¦¬ 토끼간을 μ‘°μœ¨ν•˜κΈ°κ°€ 두 버전닀 μ–΄λ ΅λ‹€λŠ” 점이닀. 그런 κ²ƒμœΌλ‘œ λ‹Ήμ‹ μ˜ ν΄λΌμ΄μ–ΈνŠΈλŠ” κ·Έλ“€μ˜ μ½”λ“œλΌ λ‹€μŒμ€‘ μ–΄λŠκ±° 같이 μž‘μ„±ν• μ§€ κ²°μ •ν• μˆ˜ μžˆλ‹€.

~cpp 
    Rational a, b, c, d, result;
    ...
    result = a + b + c + d;     // μ•„λ§ˆ 이 μ—°μ‚°μ—μ„œλŠ” 각 operaotr+λΌ ν˜ΈμΆœν• λ•Œ λ°œμƒν•˜λŠ”
                                // 3개의 μž„μ‹œ 객체가 μ‘΄μž¬ν•  것이닀.
μ΄κ±°λ‚˜ μ΄λ ‡κ²Œ 같이

~cpp 
    result = a;             // ν•˜μ§€λ§Œ μ—¬κΈ°μ—μ„œλŠ” λͺ¨λ‘ μž„μ‹œ 객체가 ν•„μš” μ—†λ‹€.
    result += b;        
    result += c;
    result += d;
μ „μžμ˜ 경우 μ“°κΈ° 쉽고, 디버그 ν•˜κΈ°λ„, μœ μ§€ λ³΄μˆ˜ν•˜κΈ°λ„ 쉽닀. 그리고 80%μ •λ„μ˜(Item 16μ°Έκ³ ) λ‚©λ“ν• λ§Œν•œ νš¨μœ¨μ„ 가지고 μžˆλ‹€. ν›„μžλŠ” μ€λ” μ „μžλ³΄λ‹€ 효율적이고 μ–΄μ…ˆλΈ”λŸ¬ ν”„λ‘œκ·Έλž˜λ¨Έλ“€μ—κ²Œ μ€λ” 직관적이라고 μƒκ°λœλ‹€. 두 버전을 μ΄μš©ν•œ μ½”λ“œλΌ λͺ¨λ‘ μ œκ³΅ν•˜μ—¬μ„œ 당신은 디버그 μ½”λ“œμ‹œμ—λŠ” μ€λ” 읽기 μ‰¬μš΄ stand-alone operatorλΌ μ‚¬μš©ν•˜λ„λ‘ ν• μˆ˜ 있고, μ°¨ν›„ νš¨μœ¨μ„ μ€‘μ‹œν•˜λŠ” κ²½μš°μ— λ‹€λ₯Έ λ²„μ „μœΌλ‘œ(more efficient assignmen) 릴리즈(Release)λΌ ν• μˆ˜ 있게 ν• μˆ˜ μžˆλ‹€. κ²Œλ‹€κ°€ stand-alone을 μ μš©μ‹œν‚€λŠ” λ²„μ „μœΌλ‘œμ„œ 당신은 ν΄λΌμ΄μ–ΈνŠΈκ°€ 두 버전을 λ°”κΏ€λ•Œ λ¬Έλ²•μ μœΌλ‘œ μ•„λ¬΄λŸ° 차이가 없도둝 ν™•μ‹  μ‹œμΌœμ•Ό ν•œλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ νš¨μœ¨λ©΄μ—μ„œμ˜ κ΄€μ μœΌλ‘œ stand-alone operator의 μ μš©μ„ 생각해 보자. λ‹€μŒμ˜ operator+λΌ μœ„ν•œ μ½”λ“œλΌ λ³΄μž:

~cpp 
    template<T>
    const T operator+(const T& lhs, const T&rhs)
    {   return T(lhs) += rhs;   }
T(lhs) λΌλŠ” ν‘œν˜„μ€ T의 볡사 μƒμ„±μžλΌ ν˜ΈμΆœν•œλ‹€. 이것은 lhs와 λ™μΌν•œ 값을 κ°€μ§€λŠ” μž„μ‹œ κ°μ²΄λΌ μƒμ„±ν•œλ‹€. 이 μž„μ‹œ κ°μ²΄λŠ” operator+=의 rhsλ‘œμ„œ 쓰이고, 그것은 operator+κ°€ λ°˜ν™˜ν•˜λŠ” κ²°κ³Ό 값이 λœλ‹€. 이 μ½”λ“œλŠ” ν•„μš”μ—†λŠ” λΉ„λ°€(cryptic)둜 보인닀. 이것 처럼 ν•˜λŠ” 것이 더 낳지 μ•Šμ„κΉŒ?:

~cpp 
    template<class T>
    const T operator+(const T& lhs, const T& rhs)
    {
        T result(lhs);
        return result += rhs;
    }
이런 ν…œν”Œλ¦Ώμ€ 거의 μœ„μ˜ μ½”λ“œμ™€ 동일해 λ³΄μ΄μ§€λ§Œ 결정적인 차이점이 μžˆλ‹€. λ°”λ‘œ λ‘λ²ˆμ§Έμ˜ νƒ¬ν”Œλ¦Ώμ€ result인 이름을 κ°€μ§€λŠ” κ°μ²΄λΌ ν¬ν•¨ν•œλ‹€λŠ” 것이닀. 이런 이름 μžˆλŠ” 객체가 μžˆλ‹€λŠ” 사싀은 μ΅œκ·Όμ— κ΅¬ν˜„λœ λ°˜ν™˜ κ°’ μ΅œμ ν™”(return value optimization, Item 20μ°Έκ³ )κ°€ operator+에 λŒ€ν•˜μ—¬ μž‘λ™ν• μˆ˜ μ—†λ‹€λŠ” 것을 의λΈν•œλ‹€. 두가지쀑 첫번째 것은 항상 λ°˜ν™˜ κ°’ μ΅œμ ν™”(return value optimization)을 μˆ˜ν–‰ν•˜κΈ°μ— μ λ‹Ήν•˜λ‹€ κ·Έλž˜μ„œ 당신이 μ‚¬μš©ν•˜λŠ” μ»΄νŒŒμΌλŸ¬κ°€ 더 쒋은 μ½”λ“œλΌ λ§Œλ“€μ–΄λ‚Ό κ°€λŠ₯성이 쑴재 ν•œλ‹€.

자, μ΄λŸ¬ν•œ 사싀듀은 λ‹€μŒκ³Ό 같은 μ½”λ“œμ— κ΄€ν•˜μ—¬ μ£Όλͺ©ν•˜κ²Œ ν•˜λŠ”λ°,

~cpp 
    return T(lhs) += rhs;
이런 μ½”λ“œλŠ”, λŒ€λ‹€μˆ˜μ˜ μ»΄νŒŒμΌλŸ¬λ“€μ΄ λ°˜ν™˜ κ°’ μ΅œμ ν™”λΌ μˆ˜ν–‰ν•˜λŠ” 것 보닀 μ²˜λ¦¬ν•˜κΈ° 더 κΉŒλ‹€λ‘­λ‹€. μ²˜μŒμ— μš°λ¦¬λŠ” ν•¨μˆ˜ μ•ˆμ—μ„œ 단지 당신이 이름 지어진 result을 μ‚¬μš©ν•˜κΈ° μœ„ν•΄ 객체에 λŒ€ν•œ λΉ„μš©μ„ μ§€λΆˆν•΄μ•Ό λœλ‹€. 이름 지어지지 μ•Šμ€(μ—†λŠ”) 객체가 이름 지어진 객체듀 보닀 더 μ œκ±°ν•˜κΈ° μ‰¬μš΄κ²ƒμ€ 사싀이닀. κ·Έλž˜μ„œ 이름 지어진 객체와 이름 지어지 μ•Šμ€(μ—†λŠ” ) κ°μ²΄λΌ μ„ νƒν•˜ 상황이 주어진닀면 당신은 μ•„λ§ˆ μž„μ‹œ μΈμžλ“€μ„ μ‚¬μš©μ„ μ„ νƒν•˜λŠ” 것이 더 쒋은 방법이닀. 그것은 νŠΉλ³„νžˆ 였래된 μ»΄νŒŒμΌλŸ¬κ°€ μ•„λ‹Œ 이상은 κ²°μ½” 이름 지어진 녀석듀보닀 더 λ§Žμ€ λΉ„μš©μ„ μ§€λΆˆν•˜μ§€ μ•ŠλŠ”λ‹€.

이름이 쑴재, λΉ„μ‘΄μž¬ 객체와 컴파일러의 μ΅œμ ν™”μ— λ‹€ν•œ μ΄μ•ΌκΈ°λŠ” μ°Έ ν₯λΈλ‘­λ‹€. ν•˜μ§€λ§Œ μ»€λ‹€λž€ μ£Όμ œλΌ μžŠμ§€ 말자. κ·Έ μ»€λ‹€λž€ μ£Όμ œλŠ” operatorν• λ‹Ή 버전과(assignment version of operator, operator+= λ”°μœ„)이 stand-alone operator적용 버전보닀 더 νš¨μœ¨μ μ΄λΌλŠ” 점이닀. 라이브러리 μ„κ³„μžμΈ 당신이 λ‘κ°€μ§€λΌ λͺ¨λ‘ μ œκ³΅ν•˜κ³ , μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ 개발자인 당신은 졜고의 μ„±λŠ₯을 μœ„ν•˜μ—¬ stand-alone operator적용 버전 보닀 operatorν• λ‹Ή 버전(assignment version of operator)의 μ‚¬μš©μ— λŒ€ν•˜μ—¬ 생각해야 할것이닀.

1.8. Item 23: Consider alternative libraries.

  • Item 23: 라이브러리 ꡐ체에 κ΄€ν•΄μ„œ 생각해 봐라.

라이브러리 λ””μžμΈμ€ ν”„λ‘œκ·Έλž¨ μ œμž‘ κ³Όμ •μ—μ„œμ˜ 쀑간물이닀.(an exercise in compromise) 이상적인 λΌμ΄λΈŒλŸ¬λ¦¬λŠ” μž‘μ•„μ•Ό ν•˜κ³ , 힘있고(powerful), μœ μ—°ν•˜λ©°, ν™•μž₯μ„±μžˆκ³ , λͺ…μ‹œμ μ΄κ³ , λ²”μš©μ μ΄κ³ , 지원이 쒋와야 ν•˜κ³ , μ‚¬μš© μžμ•½μ— μžμœ λ‘œμ›Œμ•Ό ν•˜κ³ , 버그가 μ—†μ–΄μ•Ό ν•œλ‹€. λ¬Όλ‘  쑴재 ν•˜μ§€ μ•ŠλŠ”λ‹€. μš©λŸ‰μ΄λ‚˜, 속도에 μ΅œμ ν™”λœ λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ€ 보톡 μ΄λ™ν•˜κΈ°μ— μ–΄λ ΅λ‹€.(portable:λ‹€λ₯Έ ν•˜λ“œμ›¨μ–΄ 간에 μ΄μ‹ν•˜κΈ° μ–΄λ ΅λ‹€ μ •λ„μ˜ 의λΈ) ν’λΆ€ν•œ κΈ°λŠ₯듀을 가진 λΌμ΄λΈŒλŸ¬λ¦¬λŠ” 직관적이지 λͺ»ν•˜λ‹€. 버그가 μ—†λŠ” λΌμ΄λΈŒλŸ¬λ¦¬λŠ” 일정 뢀뢄에 μ œμ•½μ΄ μžˆλ‹€. μ‹€μ„Έκ³„μ—μ„œ μš°λ¦¬λŠ” λͺ¨λ“ κ²ƒμ„ λ§Œμ± μ‹œν‚€μ§€λŠ” λͺ»ν•œλ‹€.;항상 νŠΉμ •ν•œ 어떀것을 μΆ”κ΅¬ν•˜κ²Œ λœλ‹€.

μ„œλ‘œ λ‹€λ₯Έ λ””μžμ΄λ„ˆλ“€μ΄ μ„œλ‘œ λ‹€λ₯Έ 이념(μš°μ„ μˆœμœ„)에 λ”°λΌμ„œ μ΄λŸ¬ν•œ κΈ°μ€(criteria,λ‹¨μˆ˜:criterion - κΈ°μ€)을 μ„μ •ν•œλ‹€. κ·Έλž˜μ„œ 그듀은 κ·Έλ“€μ˜ λ””μžμΈμ—μ„œ λ‹€λ₯Έ μ–΄λ–€ 것듀을 ν¬μƒν•œλ‹€. 결과적으둜 λ‘κ°œμ˜ λΌμ΄λΈŒλŸ¬λ¦¬λŠ” λΉ„μŠ·ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜μ§€λ§Œ μ™„μ „νžˆ λ‹€λ₯Έ μ„±λŠ₯을 보인닀.

예λΌλ“€μ–΄μ„œ iostreamκ³Ό stdio λΌμ΄λΈŒλŸ¬λ¦¬λΌ μƒκ°ν•΄ 보자. λ‘˜λ‹€ λͺ¨λ‘ C++ν”„λ‘œκ·Έλž˜λ¨Έμ—κ²Œ μœ νš¨ν•˜λ‹€. iostream λΌμ΄λΈŒλŸ¬λ¦¬λŠ” C에 λΉ„ν•΄ μœ λ¦¬ν•œ λͺ‡κ°€μ§€μ˜ 이점이 μžˆλ‹€. 예λΌλ“€μ–΄μ„œ iostream λΌμ΄λΈŒλŸ¬λ¦¬λŠ” ν˜• μ•ˆμ •μ μ΄κ³ (type-safe), 더 ν™•μž₯μ„± μžˆλ‹€. κ·Έλ ‡μ§€λ§Œ 효율의 κ΄€μ μ—μ„œλΌλ©΄ iostreamλΌμ΄λΈŒλŸ¬λ¦¬λŠ” stdio와 λ°˜λŒ€λ‘œ 보톡 더 떨어진닀. μ™œλƒν•˜λ©΄ stdioλŠ” 일반적으둜 oostream 보닀 더 μž‘κ³  더 λΉ λ₯΄κ²Œ μ‹€ν–‰λ˜λŠ” 결과물을 μ‚°μΆœν•΄ λ‚΄κΈ° λ•Œλ¬Έμ΄λ‹€.

μ†λ„λΌ μ²«λ²ˆμ§Έ 초점으둜 μ‚Όμ•„ 보자. iostreamκ³Ό stdio의 μ†λ„λΌ λŠλ‚„μˆ˜ μžˆλŠ” ν•œκ°€μ§€ 방법은 각기 λ‘λΌμ΄λΈŒλŸ¬λ¦¬λΌ μ‚¬μš©ν•œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λ²€μΉ˜λ§ˆν¬λΌ ν•΄λ³΄λŠ” 것이닀. 자 μ—¬κΈ°μ—μ„œ λ²€μΉ˜λ§ˆν¬μ— 거짓이 μ—†λŠ” 것이 μ€‘μš”ν•˜λ‹€. ν”„λ‘œκ·Έλž¨κ³Ό 라이브러리 μ‚¬μš©μ— μžˆμ–΄μ„œ λ§Œμ•½ 당신이 일반적인 λ°©λ²•μœΌλ‘œ μ‚¬μš©μœΌλ‘œ μž…λ ₯ν•˜λŠ” 자료(a set of inputs)듀을 μ–΄λ ΅κ²Œ λ§Œλ“€μ§€ 말아야 ν•˜κ³ , λ”λΆˆμ΄ 벀치 λ§ˆν¬λŠ” λ‹Ήμ‹ κ³Ό ν΄λΌμ΄μ–ΈνŠΈλ“€μ΄ λͺ¨λ‘ μ–Όλ§ˆλ‚˜ 일반적 인가에 λŒ€ν•œ μ‹ λ’°ν•  방법을 가지고 μžˆμ§€ μ•Šλ‹€λ©΄ 이것듀은 무용 지물이 λœλ‹€. κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  벀치 λ§ˆν¬λŠ” 각기 λ‹€λ₯Έ 문제의 μ ‘κ·Ό λ°©μ‹μœΌλ‘œ μƒλ°˜λ˜λŠ” κ²°κ³ΌλΌ μ΄λŒμˆ˜ μžˆλ‹€. κ·Έλž˜μ„œ λ²€μΉ˜λ§ˆν¬λΌ μ™„μ „νžˆ μ‹ λ’°ν•˜λŠ” 것은 λ©μ²­ν•œ μƒκ°μ΄μ§€λ§Œ, μ΄λŸ°κ²ƒλ“€μ˜ μ™„μ „νžˆ λ¬΄μ‹œν•˜λŠ” 것도 λ©μ²­ν•œ 생각이닀.

자, κ°„λ‹¨ν•œ μƒκ°μœΌλ‘œ 벀치마크 ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•΄ 보닀. ν”„λ‘œκ·Έλž¨μ€ κ°€μž₯ 근본적인 I/O κΈ°λŠ₯λ“€λ§Œμ„ μˆ˜ν–‰ν•œλ‹€. 이 ν”„λ‘œκ·Έλž¨μ€ 기본적인 μž…λ ₯κ³Ό 좜λ ₯μ—μ„œ 30,000 의 μ‹€μˆ˜λΌ μ½μ–΄ λ‚˜κ°„λ‹€. iostreamκ³Ό stdioκ°„μ˜ 선택은 μ„ μ–Έλœ 심볼(symbol) STDIO의 μœ λ¬΄μ— 따라 κ²°μ •λœλ‹€. 이 심볼이 μ„ μ–Έλ˜μ–΄ 있으면 stdio λΌμ΄λΈŒλŸ¬λ¦¬κ°€ 쓰인 것이고 μ•„λ‹ˆλΌλ©΄ iostreamλΌμ΄λΈŒλŸ¬λ¦¬κ°€ 쓰인 것이닀.

~cpp 
    #ifdef STDIO
    #include <stdio.h>
    #else
    #include <iostream>
    #include <iomanip>
    using namespace std;
    #endif

    const int VALUES = 30000;
    int main()
    {
        double d;
        for (int n = 1; n < VALUES; ++n){
      #ifdef STDIO
            scanf("%lf", &d);
            printf("%10.5f", d);
      #else
            cin >> d;
            cout << setw(10)                        // ν‘œν˜„μ„ 10 ν•„λ“œλ‘œ κ³ μ •
                 << setprecision(5)                 // μ†Œμˆ˜μ  자리수 κ²°μ •
                 << setiosflags(ios::showpoint)     // 점 보이도둝
                 << setiosflags(ios::fixed)         // 10자리 κ³ μ •μœΌλ‘œ λΆ€μ±ν•œ 자리 경우 빈자리 
                 << d;     
      #endif
            if (n % 5 == 0){
          #ifdef STDIO
                printf("\n";
          #else
                cout << '\n';
          #endif
        }
        return 0;
    }
이런 ν”„λ‘œκ·Έλž¨μ€ μ–‘μ˜ μ •μˆ˜μ˜ μž…λ ₯의 μžμ—° 둜그 값을 μ£ΌλŠ”λ°, λ‹€μŒκ³Ό 같은 κ²°κ³ΌλΌ λ³΄μΈλ‹€.

~cpp 
0.00000     0.69315     1.09861     1.38629     1.60944
1.79176     1.94591     2.07944     2.19722     2.30259
2.77259     2.48491     2.56495     2.63906     2.70805
2.77289     2.83321     2.89037     2.94444     2.99573
3.04452     3.09104     3.13549     3.17805     3.21888
μ΄λ ‡κ²Œ 좜λ ₯을 꾸며놓은 것은 νŠΉλ³„ν•œ μž‘μ—… 없이, iostream을 μ΄μš©ν•΄μ„œ κ³ μ •λœ 좜λ ₯ 양식을 해놓은 것이닀. λ¬Όλ‘ 

~cpp 
    cout << setw(10)                        
         << setprecision(5)                 
         << setiosflags(ios::showpoint)     
         << setiosflags(ios::fixed)         
         << d;     
같은 μ—¬κΈ° 이것이 같이 말이닀.

~cpp 
    printf("%10.5f", d);
κ·Έλ ‡μ§€λ§Œ operator<<λŠ” ν˜•μ•ˆμ •(type-safe)이고 ν™•μž₯μ„±(extensible)ν•˜λ‹€ 그리고 printfλŠ” 그렇지 λͺ»ν•˜λ‹€.

λ‚˜λŠ” 이 ν”„λ‘œκ·Έλž¨μ„ λͺ‡κ°€μ§€μ˜ 기계와 OSλΌ μ‘°ν•©μœΌλ‘œ λŒλ Έλ‹€. 그리고 λͺ¨λ“  경우의 μ»΄νŒŒμΌλŸ¬μ—μ„œ stdio버전이 더 λΉ¨λžλ‹€. λ•Œλ‘œ 그것은 μ•½κ°„μ—μ„œ(20%정도) ꡉμž₯ν•œ 차이(거의200%)κΉŒμ§€λ„ λ³΄μ˜€λ‹€. ν•˜μ§€λ§Œ λ‚˜λŠ” κ²°μ½” iostream의 적용이 stdio적용 보닀 λΉ λ₯Έ κ²½μš°λŠ” μ°Ύμ„μˆ˜κ°€ μ—†μ—ˆλ‹€. λ§λΆ™μ—¬μ„œ ν”„λ‘œκ·Έλž¨μ˜ 크기도 stdioκ°€ 더 μž‘μ€ κ²½ν–₯을(λ•Œλ‘œλŠ” μ•„μ£Ό 많이 차이가 λ‚œλ‹€.) 보여μ€λ‹€.(싀체 ν”„λ‘œκ·Έλž¨μ—μ„œ μ΄λŸ¬ν•œ μ°¨μ΄λŠ” 정말 μ€‘μš”ν•˜λ‹€.)

stdio의 효율의 이점은 기계에 쒅속적(implementation-dependent)μ΄λΌλŠ” 면을 생각해 보자. κ·Έλž˜μ„œ λ‚΄κ°€ ν…ŒμŠ€νŠΈν•  λΈλž˜μ˜ μ‹œμŠ€ν…œ λ“€μ΄λ‚˜, λ‚΄κ°€ ν…ŒμŠ€νŠΈν•œ 졜근의 μ‹œμŠ€ν…œλ“€μ€ 거의 λ¬΄μ‹œν•΄λ„ 쒋을 만큼 iostreamκ³Ό stdioκ°„μ˜ μž‘μ€ μ„±λŠ₯ μ°¨μ΄λΌ λ³΄μΈλ‹€. 사싀 μ–΄λ–€ λΆ€λΆ„μ—μ„œ 이둠적으둜 iostream의 적용이 stdio보닀 더 λΉ λ₯Έκ²ƒμ„ λ°”λž„μˆ˜, μ°Ύμ„μˆ˜ μžˆλ‹€. μ™œλƒν•˜λ©΄ iostream은 κ·Έλ“€μ˜ operand(인자)듀을 컴파일 νƒ€μž„μ— ν˜•μ„ ν™•μ •ν•˜κ³  stdioν•¨μˆ˜λ“€μ€ 일반적으둜 μ‹€ν–‰μ‹œκ°„μ— λ¬Έμžμ—΄λ‘œμ„œ ν•΄μ„ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

iostreamκ³Ό stdio의 이런 μƒλ°˜λ˜λŠ” μ„±λŠ₯은 단지 예둜 촛점은 μ•„λ‹ˆλ‹€. 촛점은 λΉ„μŠ·ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ΄ μ„±λŠ₯κ³Ό λ‹€λ₯Έ μΈμžλ“€κ³Όμ˜ κ΅ν™˜(trade-off)이 이루어 μ§„λŠ” 점이닀. κ·Έλž˜μ„œ 당신은 λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ—μ„œ 병λͺ©ν˜„상(bottleneck)을 λ³΄μΌλ•Œ, 병λͺ© ν˜„μƒμ„ 라이브러리 ꡐ체둜 ν•΄κ²°ν•  수 μžˆλŠ” κ²½μš°λΌ λ³Όμˆ˜ μžˆλ‹€λŠ” 점이닀. 예λΌλ“€μ–΄μ„œ λ§Œμ•½ λ‹Ήμ‹ μ˜ ν”„λ‘œκ·Έλž¨μ΄ I/O병λͺ©μ„ 가지고 μžˆλ‹€λ©΄ 당신은 μ•„λ§ˆ iostream을 stdio둜의 κ΅μ²΄λΌ μƒκ°ν•΄ 볼수 μžˆλ‹€. ν•˜μ§€λ§Œ κ·Έκ²ƒμ˜ μ‹œκ°„μ΄ 동적 λ©”λͺ¨λ¦¬ ν• λ‹Ήκ³Ό ν•΄μ œμ˜ 뢀뢄이라면 λ‹€λ₯Έ operator new와 opreator delete(Item 8μ°Έκ³ )의 ꡐ체둜 λ°©μ•ˆμ„ μƒκ°ν• μˆ˜ μžˆλ‹€. μ„œλ‘œ λ‹€λ₯Έ λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ€ νš¨μœ¨μ„±, ν™•μž₯μ„±, 이동성(이식성), ν˜•μ•ˆμ •μ„±, 그리고 λ‹€λ₯Έ μ£Όμ œμ„ κ°μ•ˆν•΄μ„œ μ„œλ‘œ λ‹€λ₯Έ λ””μžμΈμ˜ λͺ©μ μœΌλ‘œ λ§Œλ“€μ–΄ 쑌기 λ•Œλ¬Έμ— 당신은 라이브러리 ꡐ체둜 λˆˆμ— 띠게 μ„±λŠ₯ν–₯μƒμ˜ μ°¨μ΄λΌ λŠλ‚„μˆ˜ μžˆμ„ 것이닀.

1.9. Item 24: Understand the costs of virtual functions, multiple ingeritance, virtual base classes, and RTTI

  • Item 24: 가상 ν•¨μˆ˜, 닀쀑 상속, 가상 기초 클래슀, RTTI(μ‹€μ‹œκ°„ ν˜• 검사)에 λŒ€ν•œ λΉ„μš©μ„ μ΄ν•΄ν•˜λΌ.

C++μ»΄νŒŒμΌλŸ¬λŠ” μ–Έμ–΄μƒμ—μ„œ 각 νŠΉμ§•μ„ μ μš©ν• μˆ˜ μžˆλŠ” 방법을 μ°Ύμ•„μ•Όλ§Œ ν•œλ‹€. λ¬Όλ‘  그런 적용 방법은 컴파일러 의쑴적이고, λ‹€λ₯Έ μ»΄νŒŒμΌλŸ¬λŠ” λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ μ–Έμ–΄μ˜ νŠΉμ„±μ„ μ μš©ν•  것이닀. μ΄λŸ¬ν•œ λŒ€λΆ€λΆ„μ˜ λΆ€λΆ„μ—μ„œ 당신은 μ•„λ§ˆ 그런 걱정은 ν•„μš” 없을 것이닀. ν•˜μ§€λ§Œ λͺ‡κ°€μ§€ νŠΉμ§•μ˜ μ μš©μ—μ„œ μ‹€ν–‰ν”„λ‘œκ·Έλž¨μ˜ 객체와 μ†λ„μ˜ 크기 큰영ν–₯을 μ€λ‹€. κ·Έλž˜μ„œ μ΄λŸ¬ν•œ 영ν–₯을 μ£ΌλŠ” νŠΉμ§•λ“€μ— κ΄€ν•˜μ—¬ 기본적 μ΄ν•΄λΌ ν•˜κ³  μžˆλŠ”κ²ƒμ΄ μ€‘μš”ν•˜λ‹€. μ΄λŸ¬ν•œ 것쀑 κ°€μž₯ μ•žμ„  νŠΉμ§•μ΄ κ°€μƒν•¨μˆ˜(virtual function)이 될것이닀.

1.9.1. Virtual Function

가상 ν•¨μˆ˜κ°€ ν˜ΈμΆœλ λ•Œ ν•΄λ‹Ή μ½”λ“œλŠ” ν•¨μˆ˜κ°€ λΆˆλ¦¬λŠ” κ°μ²΄μ—μ„œ 동적 ν˜•(dynamic type)으둜 λ°˜μ‘ν•΄μ„œ μ‹€ν–‰λœλ‹€.;ν¬μΈν„°μ˜ ν˜•(type)μ΄λ‚˜ 객체의 μ°Έμ‘°λŠ” μ€‘μš”ν•˜μ§€ μ•Šλ‹€. μ–΄λ–»κ²Œ μ»΄νŒŒμΌλŸ¬λŠ” μ΄λŸ¬ν•œ 행동을 효율적으둜 μ œκ³΅ν• μˆ˜ μžˆμ„κΉŒ? λŒ€λ‹€μˆ˜μ˜ 적용 방법(implementations)은 virtual table(가상 ν•¨μˆ˜ ν…Œμ΄λΈ”)κ³Ό virtual table pointer(κ°€μƒν•¨μˆ˜ν…Œμ΄λΈ” 포인터)λΌ μ œκ³΅ν•œλ‹€. virtual tableκ³Ό virtual table pointerλŠ” 일반적으둜 각자 vtblsκ³Ό vptrs 둜 λŒ€μ‹  λΆ€λΌμˆ˜ μžˆλ‹€.

vtbl은 보톡 ν•¨μˆ˜ 포인터 배열이닀. (λͺ‡λͺ‡ μ»΄νŒŒμΌλŸ¬λŠ” λ°°μ—΄ λŒ€μ‹ μ— μ—°κ²° 리슀트(linked-list)λΌ μ‚¬μš©ν•˜κΈ°λ„ ν•˜μ§€λ§Œ 근본적으둜 같은 κΈ°λŠ₯을 κ΅¬ν˜„ν•œλ‹€.) ν”„λ‘œκ·Έλž¨ μƒμ—μ„œμ˜ κ·Έλƒ₯ μ„ μ–Έλ˜μ—ˆλ“ , 상속 λ°›μ•˜λœ¬ 이런 각각의 ν΄λž˜μŠ€λŠ” λͺ¨λ‘ vtbl을 가지고 μžˆλ‹€. 그리고 클래슀의 vtblμ•ˆμ— μžˆλŠ” μΈμžλ“€μ€ ν΄λž˜μŠ€μ— λŒ€ν•œ 가상 ν•¨μˆ˜μ˜ κ΅¬ν˜„ μ½”λ“œμ— μ§€μΉ­ν•˜λŠ” ν¬μΈν„°λ“€μ˜ λͺ¨μž„이닀. 예λΌλ“€μ–΄μ„œ λ‹€μŒκ³Ό 같이 ν΄λž˜μŠ€κ°€ μ„ μ–Έλ˜μ–΄ μžˆλ‹€λ©΄

~cpp 
    class C1{
    public:
        C1();
        virtual ~C1();
        virtual void f1();
        virtual int f2(char c) const;
        virtual void f3(const string&s);
        
        void f4() const;
        ...
    };
C1의 virtual table 배열은 μ•„λ§ˆ λ‹€μŒκ³Ό 같이 ν‘œν˜„λ  것이닀.


가상 ν•¨μˆ˜κ°€ μ•„λ‹Œ(nonvirtual function) f4λŠ” ν…Œμ΄λΈ”μ— κΈ°μˆ λ˜μ–΄ μžˆμ§€ μ•Šκ³ , C1의
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:48
Processing time 0.3011 sec