MoreEffectiveC++
1.1. Item 16:Remember the 80-20 rule. ¶
- Item 16:80-20 κ·μΉμ κΈ°μ΅ν΄λΌ.
80-20 κ·μΉ μ΄λ? νλ‘κ·Έλ¨μ 80%μ 리μμ€κ° 20%μ μ½λμμ μ°μ¬μ§λ€.:μ€ν μκ°μ 80%κ° λλ΅ 20%μ μ½λλ₯Ό μλͺ¨νλ€;80%μ λ©λͺ¨λ¦¬λ μ΄λ€ 20%μ μ½λμμ μ΄λ€.;80%μ disk μ κ·Όμ 20%μ μ½λμμ μ΄λ£¨μ΄μ§λ€.:80%μ μννΈμ¨μ΄ μ μ§μ λ
Έλ ₯μ(maintenance effort)λ 20%μ μ½λμ μμ λΆμ΄μ§λ€.
80-20 κ·μΉμ μλ§μ κΈ°κ³μμ, μ΄μ체μ (Operating System)μμ, κ·Έλ¦¬κ³ μ΄ν리μΌμ΄μ μμ μ μ©λλ€. 80-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μ λν μ¬μ©μ΄λΌλ©΄ λ μ΄κ±΄ λ³λ‘ μ€μν ν¬μΈν°(κ΄μ )μ΄ λμ§ μλ κ²μ΄λ€.
λλΆλΆ νλ‘κ·Έλλ¨Έλ€μ κ·Έλ€μ νλ‘κ·Έλ¨μ κ΄ν νΉμ±μ κ΄νμ¬ λ©μ²ν μ§κ΄λ ₯μ κ°μ§κ³ μλ€. μλνλ©΄ νλ‘κ·Έλ¨ μ±λ₯μ νΉμ§μ μμ£Ό μ§κ΄μ μ΄μ§ λͺ»νλ€. κ²°κ³Όμ μΌλ‘ λ¨μ λμλ λμ§ μκ³ λ§ν μ λ§μ λ Έλ ₯μ΄ μ±λ₯ ν₯μμ μν΄ νλ‘κ·Έλ¨μ κ΄λ ¨λ λΆλΆμ μμ λΆμ΄ μ§λ€. μλ₯Όλ€μ΄μ μλ§, κ³μ°μ μ΅μν μν€λ μκ³ λ¦¬μ¦κ³Ό λ°μ΄ν° κ΅¬μ‘°κ° νλ‘κ·Έλ¨μ μ μ© λλ€. κ·Έλ μ§λ§ λ§μ½μ μ μΆ(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μ μ°μμ λνμ¬ μκ°ν΄ 보μ.
λ₯λ₯ (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κ° κ³΅μ νλ λ°μ΄ν° ꡬ쑰μ μνλ ν΄λΌμ΄μΈνΈλ€μκ² λͺ ννλ€. κ·Έλ¦¬κ³ κ·Έκ²μ νμ€ν λ€μμ μ μλ μμ κ°μ΄ κ°μ μ°μ§ μκ³ μ½κΈ°λ§μ μꡬν λλ μλ¬΄λ° κ±±μ ν μ μ΄ μλ€.
μ§κΈ μμμ μ΄λ κ² μ κ·Όνλ λ°©μμ μκ³ , κ°λ¨ν λΆλΆμ μΈκΈνλκ±°μ λΆκ³Όνλ€ κ·Έλμ, λκ° λ¬΄μμ 곡μ νλμ§ μκ³ μκ³ , λ°νλλ κ°μΌλ‘, μΈκΈν 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μμμ μν κ³Ό λΉμ·ν κ²μ΄λΌ μμ) λ μ°λ¦¬κ° μμ μ μνμ¬ μ½κΈ°λ μ°κΈ° νλμ νλμ§μ κ²°μ μ μ°κΈ°νκ² νλ€.
μ΄κ²μ μ°λ¦¬μκ² μ μ© κ΄μ μμ μλΉν λμ μ΄λ€. μ°λ¦¬κ° μνλ κ²μ μ΄λ₯΄κΈ° μνμ¬ 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 ( ννμ μν κ²μΌλ₯Έ μ°μ° )
~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μ μ₯μ μ μ΄μ©ν νλ ¬ μ°μ° λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ€.
μ΄λ»κ² νμ΄μ΄λꡬ? νλ ¬ κ³μ°μ λΆμΌμ λν κ²½νμ΄ μ°λ¦¬μ μ΄λ¬ν μ½λμ λν λ Έλ ₯μ κ°λ₯μ±μ μ€λ€. μ¬μ€ 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 (μμ½)
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: μμλλ μ°μ°μ κ°μ κ³μ°ν΄ λμ΄λΌ.
μ, λ€μ μμ λ₯Ό μκ°ν΄ 보μ. μμΉ λ°μ΄ν°μ ν° 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:μμ κ°μ²΄λ€μ κΈ°λ³Έμ μ΄ν΄νμ.
~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: λ°νλλ κ°μ μ΅μ ν νλΌ
μ 리μλ₯Ό μν 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;
μ¬κΈ° κ΄λ ¨ ꡬλΆμ΄λ€.
μ΄λ° ꡬ문 μμ μ±κ³΅νλ€. κ·Έκ²λ€μ μ μ 10μ UPIntsλ‘ μμκ°μ²΄κ° μμ±μΌλ‘ μΌλ ¨μ κ³Όμ μ μνν μ μλ€.(Item 19μ°Έκ³ )
~cpp upi3 = upi1 + 10; upi3 = 10 + upi2;
μ»΄νμΌλ¬κ° μνν΄μ£Όλ μ΄λ° μ’
λ₯μ λ³νμ μ°Έ νΈνλ€. κ·Έλ μ§λ§ μ΄λ° λ³νμ μν΄ μμ±λλ μμ κ°μ²΄λ μ°λ¦¬κ° λ°λΌμ§ μμνμ§ μμ λΉμ©μ λ°μμν¨λ€. λ§μ μ¬λλ€μ λ¨μ§, μ΄λ¬ν μμ
μ λνμ¬ μλ¬΄λ° λΉμ©μ μ§λΆνμ§ μκΈ°λ₯Ό λ°λΌλκ² μ²λΌ λλ€μ C++ νλ‘κ·Έλλ¨Έλ€λ μμμ νλ³νμ΄ λΉμ©μ μλ¬΄λ° μν₯μ λΌμΉμ§ μκΈ°λ₯Ό μνλ€. κ·Έλ μ§λ§ μ΄λ° κ³μ°μμ΄ κ³Όμ° μ΄λ»κ² μνν μ μμκΉ?
νκ±Έμ λ€λ‘ λ¬Όλ¬μμ, μ°λ¦¬μ λͺ©νλ νλ³ν μ΄ μλ operator+λ₯Ό UPIntμ intꡬλΆμ νΌν©μΌλ‘ νΈμΆν μ μκ² λ§λ€μ μμμ μμ μλ€. μμμ νλ³νμ λ¬Έμ κ° λλ¬κ² κ°λ€. κ·Έλ¬λ©΄, νΌλμ€λ° μλ―Έμ μ’
μ§λΆλ₯Ό μ°μ΄ 보μ. μ¬κΈ° operator+μ μνμ μ±κ³΅μν€λ λ λ€λ₯Έ νΌν©λ(mixed-type) νΈμΆ λ°©μμ΄ μλ€. κ·Έκ²μ μ²μ μλν λ°©λ²μμ μμμ νλ³νμ μ κ±°ν΄ μ€κ²μ΄λ€. λ§μ½ μ°λ¦¬κ° UPIntμ intλ₯Ό ν©μ ν μ μκΈ°λ₯Ό μνλ€λ©΄ μ°λ¦¬λ κ·Έκ±Έ μ λΆλ€ κ·Έλ κ² κ·Έλλ‘ λ§λ λ€. λͺκ°μ ν¨μλ₯Ό κ°κΈ° λ€λ₯Έ μΈμ ν(parameter type)μΌλ‘ overloadν΄μ μ μΈν΄ λ²λ¦¬λ κ²μ΄λ€.
μ°λ¦¬λ νλ³νμ μ κ±°νκΈ° μνμ¬ overloadλ₯Ό νμλ€. νμ§λ§ λ€μκ³Ό κ°μ κ²½μ° λ¬Έμ κ° λ°μν μ μλ€
μ μ΄μ μ μκ°ν΄ 보μ. UPIntμ intμ νμ μν΄μ μ°λ¦¬λ λͺ¨λ κ°λ₯ν μΈμλ€μ operator+μ ꡬννκΈ°λ₯Ό μνλ€. μ μμ μμ μ μΈκ°μ§μ overloadingμ μ μνλμ§λ§ μ μΈμκ° λͺ¨λ intμΈ κ²½μ°μλ λμ§ μλλ€. μ°λ¦¬λ μ΄κ²λ§μ Έ μνν μ μκΈ°λ₯Ό λ°λλ€.
~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;
~cpp const UPInt operator+(const int lhs, const int rhs);
μ΄μ±μ μ΄κ±°λ, μλκ±°λ, μ΄ 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;
μ’μ λ°©λ²μ κ° operatorμ stand-alone versionκ°μ μμ°μ€λ¬μ΄ κ΄κ³λ₯Ό μκ°ν΄μ ꡬνν΄ μ£Όλ κ²μ΄λ€. μ΄κ²μ μμ΄ μμ΄λ€.
μ΄ μμ λ operator+=κ³Ό operator-=μ΄ λ€λ₯Έκ³³μ ꡬνλμ΄ μλ κ²μ΄κ³ , operator+μ operator-κ° μ΄λ€μ μ΄μ©ν΄ κ°κΈ° κΈ°λ₯μ ꡬνν λͺ¨μ΅μ΄λ€. μ΄λ° λμμΈμ΄λΌλ©΄, μ΄ operatorλ€μκ² ν λΉλ κΈ°λ₯μ μ μ§λ κ²μ΄λ€.(λ€λ₯Έ κ²μ΄ λ³νλ©΄ κ°μ΄ λ³νλ€λ μ리) κ²λ€κ° public μΈν°νμ΄μ€μμ operatorλ€μ΄ ν λΉλ λ²μ μμ ν΄λμ€ μμμ friendλ‘μ stand-alone operatorμ λν νμμ±μ μλ€.
~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; }
λ§μ½ λΉμ μ΄ λͺ¨λ μ μ 곡κ°μμ μλ stand-alone operatorλ€μ κ΄νμ¬ λ§μμ λμΉ λͺ»νλ€λ©΄, λ€μκ³Ό κ°μ templateμ μ¬μ©ν΄μ stand-alone ν¨μλ€μ μ¬μ©μ μ κ±°ν μ μλ€.:
λ€μκ³Ό κ°μ ν
νλ¦Ώμ μ¬μ©μΌλ‘ operator ν λΉ λ²μ μ΄ μ΄λ ν ν Tλ‘ μ μλμ΄μ Έ μλ μνλΌλ©΄ stand-alone operatorλ μλ§λ μλμ μΌλ‘ κ·Έκ²μ μμ±νκ² λ κ²μ΄λ€.
~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ν λΉ λ²μ μ stnad-alone λ²μ μ λΉνμ¬ ν¨μ¨μ΄ μ’λ€. μλνλ©΄ stand-alone λ²μ μ λ°λμ μλ‘μ΄ κ°μ²΄λ₯Ό λ°ννκ³ , κ·Έκ²μ μ°λ¦¬μκ² μμ κ°μ²΄μ μμ±κ³Ό νκ΄΄μ λΉμ©μ μΌκΈ°νλ€.(Item 19, 20μ°Έκ³ ) operator ν λΉ λ²μ μ κ·Έλ€μ μΌμͺ½ μΈμλ₯Ό κΈ°λ‘νλ€ κ·Έλμ ν΄λΉ operatorμ κ°μ²΄ λ°νμμ μλ¬΄λ° μμ μΈμλ₯Ό μμ±ν νμκ° μλ€.
λλ²μ§Έλ‘ μ€μν μ μ operator ν λΉ λ²μ μ stand-alone λ²μ λ§νΌ μ 곡νλ κ²μ, λΉμ μ ν΄λμ€λ₯Ό μ¬μ©νλ ν΄λΌμ΄μΈνΈλ€μκ² ν¨μ¨κ³Ό νΈμ΄μ± μ΄ λλ§λ¦¬ ν λΌκ°μ μ‘°μ¨νκΈ°κ° λ λ²μ λ€ μ΄λ ΅λ€λ μ μ΄λ€. κ·Έλ° κ²μΌλ‘ λΉμ μ ν΄λΌμ΄μΈνΈλ κ·Έλ€μ μ½λλ₯Ό λ€μμ€ μ΄λκ±° κ°μ΄ μμ±ν μ§ κ²°μ ν μ μλ€.
μ΄κ±°λ μ΄λ κ² κ°μ΄
μ μμ κ²½μ° μ°κΈ° μ½κ³ , λλ²κ·Έ νκΈ°λ, μ μ§ λ³΄μνκΈ°λ μ½λ€. κ·Έλ¦¬κ³ 80%μ λμ(Item 16μ°Έκ³ ) λ©λν λ§ν ν¨μ¨μ κ°μ§κ³ μλ€. νμλ μ’λ μ μλ³΄λ€ ν¨μ¨μ μ΄κ³ μ΄μ
λΈλ¬ νλ‘κ·Έλλ¨Έλ€μκ² μ’λ μ§κ΄μ μ΄λΌκ³ μκ°λλ€. λ λ²μ μ μ΄μ©ν μ½λλ₯Ό λͺ¨λ μ 곡νμ¬μ λΉμ μ λλ²κ·Έ μ½λμμλ μ’λ μ½κΈ° μ¬μ΄ stand-alone operatorλ₯Ό μ¬μ©νλλ‘ ν μ μκ³ , μ°¨ν ν¨μ¨μ μ€μνλ κ²½μ°μ λ€λ₯Έ λ²μ μΌλ‘(more efficient assignmen) 릴리μ¦(Release)λ₯Ό ν μ μκ² ν μ μλ€. κ²λ€κ° 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;
λ§μ§λ§μΌλ‘ ν¨μ¨λ©΄μμμ κ΄μ μΌλ‘ stand-alone operatorμ μ μ©μ μκ°ν΄ 보μ. λ€μμ operator+λ₯Ό μν μ½λλ₯Ό 보μ:
T(lhs) λΌλ ννμ Tμ λ³΅μ¬ μμ±μλ₯Ό νΈμΆνλ€. μ΄κ²μ lhsμ λμΌν κ°μ κ°μ§λ μμ κ°μ²΄λ₯Ό μμ±νλ€. μ΄ μμ κ°μ²΄λ operator+=μ rhsλ‘μ μ°μ΄κ³ , κ·Έκ²μ operator+κ° λ°ννλ κ²°κ³Ό κ°μ΄ λλ€. μ΄ μ½λλ νμμλ λΉλ°(cryptic)λ‘ λ³΄μΈλ€. μ΄κ² μ²λΌ νλ κ²μ΄ λ λ³μ§ μμκΉ?:
μ΄λ° ν
νλ¦Ώμ κ±°μ μμ μ½λμ λμΌν΄ 보μ΄μ§λ§ κ²°μ μ μΈ μ°¨μ΄μ μ΄ μλ€. λ°λ‘ λλ²μ§Έμ ν¬νλ¦Ώμ resultμΈ μ΄λ¦μ κ°μ§λ κ°μ²΄λ₯Ό ν¬ν¨νλ€λ κ²μ΄λ€. μ΄λ° μ΄λ¦ μλ κ°μ²΄κ° μλ€λ μ¬μ€μ μ΅κ·Όμ ꡬνλ λ°ν κ° μ΅μ ν(return value optimization, Item 20μ°Έκ³ )κ° operator+μ λνμ¬ μλν μ μλ€λ κ²μ μλ―Ένλ€. λκ°μ§μ€ 첫λ²μ§Έ κ²μ νμ λ°ν κ° μ΅μ ν(return value optimization)μ μννκΈ°μ μ λΉνλ€ κ·Έλμ λΉμ μ΄ μ¬μ©νλ μ»΄νμΌλ¬κ° λ μ’μ μ½λλ₯Ό λ§λ€μ΄λΌ κ°λ₯μ±μ΄ μ‘΄μ¬ νλ€.
~cpp template<T> const T operator+(const T& lhs, const T&rhs) { return T(lhs) += rhs; }
~cpp template<class T> const T operator+(const T& lhs, const T& rhs) { T result(lhs); return result += rhs; }
μ, μ΄λ¬ν μ¬μ€λ€μ λ€μκ³Ό κ°μ μ½λμ κ΄νμ¬ μ£Όλͺ©νκ² νλλ°,
μ΄λ° μ½λλ, λλ€μμ μ»΄νμΌλ¬λ€μ΄ λ°ν κ° μ΅μ νλ₯Ό μννλ κ² λ³΄λ€ μ²λ¦¬νκΈ° λ κΉλ€λ‘λ€. μ²μμ μ°λ¦¬λ ν¨μ μμμ λ¨μ§ λΉμ μ΄ μ΄λ¦ μ§μ΄μ§ resultμ μ¬μ©νκΈ° μν΄ κ°μ²΄μ λν λΉμ©μ μ§λΆν΄μΌ λλ€. μ΄λ¦ μ§μ΄μ§μ§ μμ(μλ) κ°μ²΄κ° μ΄λ¦ μ§μ΄μ§ κ°μ²΄λ€ λ³΄λ€ λ μ κ±°νκΈ° μ¬μ΄κ²μ μ¬μ€μ΄λ€. κ·Έλμ μ΄λ¦ μ§μ΄μ§ κ°μ²΄μ μ΄λ¦ μ§μ΄μ§ μμ(μλ ) κ°μ²΄λ₯Ό μ νν μν©μ΄ μ£Όμ΄μ§λ€λ©΄ λΉμ μ μλ§ μμ μΈμλ€μ μ¬μ©μ μ ννλ κ²μ΄ λ μ’μ λ°©λ²μ΄λ€. κ·Έκ²μ νΉλ³ν μ€λλ μ»΄νμΌλ¬κ° μλ μ΄μμ κ²°μ½ μ΄λ¦ μ§μ΄μ§ λ
μλ€λ³΄λ€ λ λ§μ λΉμ©μ μ§λΆνμ§ μλλ€.
~cpp return T(lhs) += rhs;
μ΄λ¦μ΄ μ‘΄μ¬, λΉμ‘΄μ¬ κ°μ²΄μ μ»΄νμΌλ¬μ μ΅μ νμ λ€ν μ΄μΌκΈ°λ μ°Έ ν₯λ―Έλ‘λ€. νμ§λ§ 컀λ€λ μ£Όμ λ₯Ό μμ§ λ§μ. κ·Έ 컀λ€λ μ£Όμ λ 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: λΌμ΄λΈλ¬λ¦¬ κ΅μ²΄μ κ΄ν΄μ μκ°ν΄ λ΄λΌ.
μλ‘ λ€λ₯Έ λμμ΄λλ€μ΄ μλ‘ λ€λ₯Έ μ΄λ
(μ°μ μμ)μ λ°λΌμ μ΄λ¬ν κΈ°μ€(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λΌμ΄λΈλ¬λ¦¬κ° μ°μΈ κ²μ΄λ€.
μ΄λ° νλ‘κ·Έλ¨μ μμ μ μμ μ
λ ₯μ μμ° λ‘κ·Έ κ°μ μ£Όλλ°, λ€μκ³Ό κ°μ κ²°κ³Όλ₯Ό 보μΈλ€.
μ΄λ κ² μΆλ ₯μ κΎΈλ©°λμ κ²μ νΉλ³ν μμ
μμ΄, iostreamμ μ΄μ©ν΄μ κ³ μ λ μΆλ ₯ μμμ ν΄λμ κ²μ΄λ€. λ¬Όλ‘
κ°μ μ¬κΈ° μ΄κ²μ΄ κ°μ΄ λ§μ΄λ€.
κ·Έλ μ§λ§ operator<<λ νμμ (type-safe)μ΄κ³ νμ₯μ±(extensible)νλ€ κ·Έλ¦¬κ³ printfλ κ·Έλ μ§ λͺ»νλ€.
~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
~cpp cout << setw(10) << setprecision(5) << setiosflags(ios::showpoint) << setiosflags(ios::fixed) << d;
~cpp printf("%10.5f", d);
λλ μ΄ νλ‘κ·Έλ¨μ λͺκ°μ§μ κΈ°κ³μ 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(μ€μκ° ν κ²μ¬)μ λν λΉμ©μ μ΄ν΄νλΌ.
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μμ μλ μΈμλ€μ ν΄λμ€μ λν κ°μ ν¨μμ ꡬν μ½λμ μ§μΉνλ ν¬μΈν°λ€μ λͺ¨μμ΄λ€. μλ₯Όλ€μ΄μ λ€μκ³Ό κ°μ΄ ν΄λμ€κ° μ μΈλμ΄ μλ€λ©΄
C1μ virtual table λ°°μ΄μ μλ§ λ€μκ³Ό κ°μ΄ ννλ κ²μ΄λ€.
~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; ... };
κ°μ ν¨μκ° μλ(nonvirtual function) f4λ ν
μ΄λΈμ κΈ°μ λμ΄ μμ§ μκ³ , C1μ