πŸš€ C++ Modules: 절차적 μ‚¬κ³ μ—μ„œ 객체 μ§€ν–₯κ³Ό μ œλ„€λ¦­ ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œμ˜ νŒ¨λŸ¬λ‹€μž„ μ „ν™˜

42μ„œμšΈμ˜ C++ Module κ³Όμ •μ˜ ν”„λ‘œμ νŠΈλ“€μ€ C언어에 클래슀λ₯Ό λ”ν•˜λŠ” μˆ˜μ€€μ„ λ„˜μ–΄, ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„ 자체λ₯Ό 근본적으둜 μ „ν™˜ν•˜λŠ” 여정이닀.

이 과정은 절차적 ν”„λ‘œκ·Έλž˜λ°(Procedural Programming)의 ν•œκ³„λ₯Ό μΈμ§€ν•˜κ³ , λ³΅μž‘ν•œ μ‹œμŠ€ν…œμ„ κ΅¬μ‘°ν™”ν•˜λŠ” μƒˆλ‘œμš΄ 방법둠인 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ°(Object-Oriented Programming)을 μ²΄λ“ν•˜λ©°, λ‚˜μ•„κ°€ μ½”λ“œμ˜ μž¬μ‚¬μš©μ„±μ„ κ·ΉλŒ€ν™”ν•˜λŠ” μ œλ„€λ¦­ ν”„λ‘œκ·Έλž˜λ°(Generic Programming)의 μ„Έκ³„κΉŒμ§€ νƒν—˜ν•˜λ„λ‘ μ„€κ³„λ˜μ–΄ μžˆλ‹€.

각 λͺ¨λ“ˆμ€ C++λΌλŠ” λ©€ν‹° νŒ¨λŸ¬λ‹€μž„ μ–Έμ–΄κ°€ μ œκ³΅ν•˜λŠ” νŠΉμ • μ² ν•™κ³Ό 도ꡬλ₯Ό 깊이 있게 νŒŒκ³ λ“œλŠ” 독립적인 연ꡬ κ³Όμ œμ΄λ‹€. 이 전체 과정을 톡해 κ°œλ°œμžλŠ” 문제의 성격에 따라 μ μ ˆν•œ νŒ¨λŸ¬λ‹€μž„μ„ μ„ νƒν•˜κ³  μ‘°ν•©ν•  수 μžˆλŠ” 폭넓은 μ‹œμ•Όμ™€ κ°•λ ₯ν•œ 무기λ₯Ό κ°–μΆ”κ²Œ λœλ‹€.


πŸ—ΊοΈ λͺ¨λ“ˆλ³„ νƒν—˜ 일지: κ°œλ…μ˜ 심측 뢄석

πŸ”Ή Module 00: C++의 κΈ°λ³Έ 골격 - β€˜C with Classes’

  • 핡심 κ°œλ…: μΊ‘μŠν™”(Encapsulation). Cμ–Έμ–΄μ˜ ꡬ쑰체와 ν•¨μˆ˜κ°€ λΆ„λ¦¬λ˜μ–΄ 있던 것과 달리, ν΄λž˜μŠ€λŠ” 데이터(멀버 λ³€μˆ˜)와 κ·Έ 데이터λ₯Ό μ‘°μž‘ν•˜λŠ” ν–‰μœ„(멀버 ν•¨μˆ˜)λ₯Ό ν•˜λ‚˜μ˜ λ‹¨μœ„λ‘œ λ¬ΆλŠ”λ‹€. μ΄λŠ” 객체의 μƒνƒœλ₯Ό μ™ΈλΆ€λ‘œλΆ€ν„° λ³΄ν˜Έν•˜κ³ , λͺ…ν™•ν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν†΅ν•΄μ„œλ§Œ μƒν˜Έμž‘μš©ν•˜λ„λ‘ κ°•μ œν•˜λŠ” μ²«κ±ΈμŒμ΄λ‹€.
  • μ£Όμš” 과제: Account 클래슀 등을 톡해 μƒμ„±μž(Constructor), μ†Œλ©Έμž(Destructor)의 κ°œλ…μ„ 읡히고, 객체의 생성과 μ†Œλ©Έμ΄λΌλŠ” 생λͺ…μ£ΌκΈ°(Life Cycle)λ₯Ό 직접 κ΄€λ¦¬ν•˜κΈ° μ‹œμž‘ν•œλ‹€. μ΄λŠ” C++의 κ°€μž₯ μ€‘μš”ν•œ μ² ν•™ 쀑 ν•˜λ‚˜μΈ RAII(Resource Acquisition Is Initialization)의 기반이 λœλ‹€. 이 κ³Όμ œλΆ€ν„° β€˜μƒλͺ…주기’ λΌλŠ” κ°œλ…μ„ μ΄ν•΄ν•˜κΈ° μ‹œμž‘ν–ˆλ‹€. ν”„λ‘œκ·Έλž¨μ΄λ‚˜, 객체 λ“±, κΈ°μ‘΄μ—λŠ” λ‘œμ§μ΄λž€ μ°¨μ›μ—μ„œ μ ‘κ·Ό ν•˜λ‹€κ°€, ν•΄λ‹Ή 과제λ₯Ό ν•˜λ©΄μ„œλΆ€ν„° μ£ΌκΈ°λΌλŠ” κ΄€μ μ—μ„œ 바라볼 수 있게 λ˜μ—ˆλ‹€.

πŸ”Ή Module 01: μžμ›μ˜ 생λͺ…μ£ΌκΈ° 관리 - RAII와 μ°Έμ‘°

  • 핡심 κ°œλ…: μžμ› 관리(Resource Management). Cμ–Έμ–΄μ˜ malloc/free와 달리, C++μ—μ„œλŠ” new/delete μ—°μ‚°μžλ₯Ό 톡해 객체의 동적 할당을 μˆ˜ν–‰ν•œλ‹€. μ—¬κΈ°μ„œ 핡심은 μƒμ„±μžμ—μ„œ μžμ›μ„ ν• λ‹Ήν•˜κ³ (new) μ†Œλ©Έμžμ—μ„œ ν•΄μ œ(delete)ν•˜λŠ” RAII νŒ¨ν„΄μ„ 톡해, μžμ›μ˜ λˆ„μˆ˜λ₯Ό μ›μ²œμ μœΌλ‘œ λ°©μ§€ν•˜λŠ” 것이닀.
  • μ£Όμš” 과제: Zombie 클래슀λ₯Ό 톡해 동적 ν• λ‹Ήλœ 객체의 생λͺ…μ£ΌκΈ°λ₯Ό κ΄€λ¦¬ν•˜λ©° RAIIλ₯Ό μ—°μŠ΅ν•œλ‹€. λ˜ν•œ, 포인터와 달리 null을 ν—ˆμš©ν•˜μ§€ μ•Šκ³ , κ°€λ¦¬ν‚€λŠ” λŒ€μƒμ„ λ³€κ²½ν•  수 μ—†λŠ” 참쑰자(Reference)λ₯Ό 톡해 더 μ•ˆμ „ν•˜κ³  λͺ…ν™•ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” 법을 λ°°μš΄λ‹€.

πŸ”Ή Module 02: μ—°μ‚°μž μ˜€λ²„λ‘œλ”© - μ‚¬μš©μž μ •μ˜ νƒ€μž…μ˜ 직관성

  • 핡심 κ°œλ…: μ—°μ‚°μž μ˜€λ²„λ‘œλ”©(Operator Overloading). μ•„μ£Ό 유우λͺ…ν•œ 개발 κ°œλ…μœΌλ‘œ μ‚¬μš©μžκ°€ 직접 μ •μ˜ν•œ 클래슀(User-Defined Type)λ₯Ό int, doubleκ³Ό 같은 λ‚΄μž₯ νƒ€μž…(Built-in Type)처럼 μžμ—°μŠ€λŸ½κ²Œ μ‚¬μš©ν•  수 μžˆλ„λ‘ λ§Œλ“œλŠ” κΈ°μˆ μ΄λ‹€. μ΄λŠ” μ½”λ“œμ˜ 가독성과 직관성을 κ·ΉλŒ€ν™”ν•œλ‹€.
  • μ£Όμš” 과제: κ³ μ • μ†Œμˆ˜μ  숫자λ₯Ό ν‘œν˜„ν•˜λŠ” Fixed 클래슀λ₯Ό λ§Œλ“€κ³ , 사칙연산, 비ꡐ, 증감 μ—°μ‚°μž 등을 λͺ¨λ‘ μ˜€λ²„λ‘œλ”©ν•œλ‹€. 이 과정을 톡해 μ •κ·œ ν˜•μ‹(Canonical Form)의 μ€‘μš”μ„±, 즉 클래슀λ₯Ό μ˜¬λ°”λ₯΄κ²Œ λ™μž‘μ‹œν‚€κΈ° μœ„ν•΄ ν•„μˆ˜μ μœΌλ‘œ κ΅¬ν˜„ν•΄μ•Ό ν•˜λŠ” μƒμ„±μž, μ†Œλ©Έμž, 볡사 μƒμ„±μž, ν• λ‹Ή μ—°μ‚°μž λ“±μ˜ 집합을 μ΄ν•΄ν•˜κ²Œ λœλ‹€.

πŸ”Ή Module 03: 상속 - μ½”λ“œ μž¬μ‚¬μš©κ³Ό β€˜is-a’ κ΄€κ³„μ˜ ν‘œν˜„

  • 핡심 κ°œλ…: 상속(Inheritance). 객체 μ§€ν–₯의 핡심 κΈ°λ‘₯ 쀑 ν•˜λ‚˜λ‘œ, κΈ°μ‘΄ 클래슀의 κΈ°λŠ₯을 μž¬μ‚¬μš©ν•˜κ³  ν™•μž₯ν•  수 있게 ν•œλ‹€. μ΄λŠ” μ½”λ“œμ˜ 쀑볡을 μ œκ±°ν•˜κ³  클래슀 κ°„μ˜ β€˜is-a’ 관계(예: ScavTrap is a ClapTrap)λ₯Ό λͺ…ν™•ν•˜κ²Œ ν‘œν˜„ν•œλ‹€.
  • μ£Όμš” 과제: DiamondTrap κ΅¬ν˜„μ„ 톡해 닀쀑 상속 μ‹œ λ°œμƒν•  수 μžˆλŠ” 닀이아λͺ¬λ“œ 문제(Diamond Problem), 즉 λΆ€λͺ¨ 클래슀의 멀버가 μ€‘λ³΅μœΌλ‘œ μƒμ†λ˜λŠ” λͺ¨ν˜Έμ„±μ„ λ§ˆμ£Όν•œλ‹€. 이λ₯Ό 가상 상속(Virtual Inheritance)으둜 ν•΄κ²°ν•˜λ©°, λ³΅μž‘ν•œ 클래슀 계측 ꡬ쑰λ₯Ό μ˜¬λ°”λ₯΄κ²Œ μ„€κ³„ν•˜λŠ” 방법을 λ°°μš΄λ‹€.

πŸ”Ή Module 04: λ‹€ν˜•μ„± - 컴파일 νƒ€μž„μ„ λ„˜μ–΄ λŸ°νƒ€μž„μœΌλ‘œ

  • 핡심 κ°œλ…: λ‹€ν˜•μ„±(Polymorphism). 기반 클래슀 ν¬μΈν„°λ‚˜ μ°Έμ‘°λ₯Ό 톡해 νŒŒμƒ 클래슀의 객체λ₯Ό λ‹€λ£° 수 있게 ν•˜λŠ”, 객체 μ§€ν–₯의 μ •μˆ˜μ΄λ‹€. μ΄λŠ” 가상 ν•¨μˆ˜(Virtual Function)λ₯Ό 톡해 κ΅¬ν˜„λ˜λ©°, 동적 바인딩(Dynamic Binding), 즉 μ‹€μ œ 호좜될 ν•¨μˆ˜κ°€ 컴파일 μ‹œμ μ΄ μ•„λ‹Œ λŸ°νƒ€μž„μ— κ²°μ •λ˜λ„λ‘ ν•œλ‹€.
  • μ£Όμš” 과제: Animalκ³Ό 같은 좔상 κΈ°λ³Έ 클래슀(Abstract Base Class)λ₯Ό 순수 가상 ν•¨μˆ˜(=0)λ₯Ό μ΄μš©ν•΄ μ •μ˜ν•œλ‹€. μ΄λŠ” νŒŒμƒ ν΄λž˜μŠ€κ°€ λ°˜λ“œμ‹œ κ΅¬ν˜„ν•΄μ•Ό ν•  μΈν„°νŽ˜μ΄μŠ€(Interface)λ₯Ό κ°•μ œν•˜λŠ” 역할을 ν•œλ‹€. λ˜ν•œ, 기반 클래슀 ν¬μΈν„°λ‘œ 객체λ₯Ό μ‚­μ œν•  λ•Œ λ°œμƒν•  수 μžˆλŠ” λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ₯Ό 막기 μœ„ν•΄ 가상 μ†Œλ©Έμž(Virtual Destructor)의 ν•„μš”μ„±μ„ μ²΄λ“ν•œλ‹€.

πŸ”Ή Module 05: μ˜ˆμ™Έ 처리 - 였λ₯˜μ— λŒ€ν•œ κ²¬κ³ ν•œ λŒ€μ‘

  • 핡심 κ°œλ…: μ˜ˆμ™Έ 처리(Exception Handling). Cμ–Έμ–΄μ˜ λ°˜ν™˜ 값을 ν†΅ν•œ 였λ₯˜ 처리 λ°©μ‹μ˜ ν•œκ³„λ₯Ό κ·Ήλ³΅ν•˜κ³ , 였λ₯˜ 처리 둜직과 정상적인 μ‹€ν–‰ λ‘œμ§μ„ λΆ„λ¦¬ν•˜λŠ” ν˜„λŒ€μ μΈ 방법이닀. try-catch-throw ꡬ문을 톡해 μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμ„ λ•Œ ν”„λ‘œκ·Έλž¨μ˜ 흐름을 μ•ˆμ „ν•˜κ²Œ μ œμ–΄ν•˜κ³ , μŠ€νƒ ν’€κΈ°(Stack Unwinding)λ₯Ό 톡해 μ§€μ—­ κ°μ²΄λ“€μ˜ μ†Œλ©Έμžλ₯Ό ν˜ΈμΆœν•˜μ—¬ μžμ›μ„ μ•ˆμ „ν•˜κ²Œ ν•΄μ œν•œλ‹€. 이 과제λ₯Ό ν•΄λ³Έ 이래둜 try-catch 의 μ€‘μš”μ„±μ„ μ΄ν•΄ν–ˆμœΌλ‚˜, μ—¬μ „νžˆ μ•„μ‰¬μš΄ 점은 μ–΄λ–€ μ‹μœΌλ‘œ κ΄€λ¦¬ν•˜λŠ” 것이 쒋은가? 에 λŒ€ν•΄μ„  항상 μ• λ§€ν•˜λ‹€λŠ” 점이닀.

πŸ”Ή Module 06: C++ ν˜•λ³€ν™˜ - λͺ…μ‹œμ μ΄κ³  μ•ˆμ „ν•œ νƒ€μž… λ³€ν™˜

  • 핡심 κ°œλ…: μ˜λ„λ₯Ό λͺ…μ‹œν•˜λŠ” ν˜•λ³€ν™˜. C μŠ€νƒ€μΌμ˜ λ¬΄λΆ„λ³„ν•œ ν˜•λ³€ν™˜ λŒ€μ‹ , C++은 static_cast, dynamic_cast, const_cast, reinterpret_cast의 λ„€ κ°€μ§€ λͺ…μ‹œμ  캐슀트λ₯Ό μ œκ³΅ν•œλ‹€. μ΄λŠ” 개발자의 μ˜λ„λ₯Ό μ½”λ“œμ— λͺ…ν™•νžˆ λ“œλŸ¬λ‚΄κ³ , μ»΄νŒŒμΌλŸ¬κ°€ 더 λ§Žμ€ 였λ₯˜λ₯Ό κ²€μΆœν•  수 μžˆλ„λ‘ λ•λŠ”λ‹€.
  • μ£Όμš” 과제: dynamic_castλ₯Ό 톡해 λŸ°νƒ€μž„μ— νƒ€μž… 정보λ₯Ό ν™•μΈν•˜λ©° μ•ˆμ „ν•˜κ²Œ λ‹€μš΄μΊμŠ€νŒ…(Down-casting)ν•˜λŠ” 방법을 μ΅νžŒλ‹€. 이 κ°œλ…λ“€ μžμ²΄λŠ” 이해가 μ‰¬μ› μ§€λ§Œ, 결과적으둜 ν˜•λ³€ν™˜ κ³Όμ •μ˜ μ—λŸ¬ν•Έλ“€λ§μ΄λΌλ˜κ°€.. ν• κ²Œ λ§Žμ•˜λ‹€.

πŸ”Ή Module 07: ν…œν”Œλ¦Ώ - μ½”λ“œμ˜ μΌλ°˜ν™”μ™€ μ œλ„€λ¦­ ν”„λ‘œκ·Έλž˜λ°

  • 핡심 κ°œλ…: μ œλ„€λ¦­ ν”„λ‘œκ·Έλž˜λ°(Generic Programming). νŠΉμ • μžλ£Œν˜•μ— μ’…μ†λ˜μ§€ μ•Šκ³ , λ‹€μ–‘ν•œ μžλ£Œν˜•μ— λŒ€ν•΄ λ™μž‘ν•  수 μžˆλŠ” λ²”μš©μ μΈ μ½”λ“œ(ν•¨μˆ˜ ν…œν”Œλ¦Ώ, 클래슀 ν…œν”Œλ¦Ώ)λ₯Ό μž‘μ„±ν•˜λŠ” νŒ¨λŸ¬λ‹€μž„μ΄λ‹€. μ΄λŠ” 컴파일 νƒ€μž„ λ‹€ν˜•μ„±μ„ 톡해 μ½”λ“œ 쀑볡을 μ΅œμ†Œν™”ν•˜λ©΄μ„œλ„ νƒ€μž… μ•ˆμ „μ„±κ³Ό μ„±λŠ₯을 λͺ¨λ‘ ν™•λ³΄ν•œλ‹€. 이 뢀뢄은 κ°€μž₯ ν₯λ―Έλ‘œμš°λ©΄μ„œλ„, 재미있던, κ·ΈλŸ¬λ‚˜ λ™μ‹œμ— κ³Όμ—° μ–΄λ–»κ²Œ 써야 ν•˜λŠ”κ°€? λΌλŠ” μ°¨μ›μ—μ„œ 고민이 된 κΈ°μˆ μ΄μ—ˆλ‹€. λ‹€λ₯Έ μ–Έμ–΄ ν”„λ‘œκ·Έλž˜λ° κ³Όμ •μ—μ„œλ„ μ œλ„€λ¦­μŠ€λŠ” κΌ­ λ‚˜μ˜€κ³ , μ‹€μ œλ‘œλ„ μ€‘μš”ν•œ 것은 μ‚¬μ‹€μ΄μ§€λ§Œ, μ œλ„€λ¦­μŠ€κ°€ μ‹€μ œ μ„œλΉ„μŠ€μ—μ„œ 운용되게 되면, μ–΄μ§€κ°„ν•˜λ©΄ λ³΅μž‘λ„λ₯Ό 높이고 μƒν˜Έ μ†Œν†΅μ΄ μ•ˆλ˜λ©΄ 기술 뢀채가 λ˜λŠ” λŠλ‚Œμ΄λΌβ€¦ μ μ ˆν•œ 쒋은 λ ˆνΌλŸ°μŠ€κ°€ λ λ§Œν•œ 사둀가 μžˆλ‚˜? μ‹Άμ—ˆλ‹€.

πŸ”Ή Module 08: STL - μ»¨ν…Œμ΄λ„ˆ, 반볡자, μ•Œκ³ λ¦¬μ¦˜μ˜ μ‚Όμœ„μΌμ²΄

  • 핡심 κ°œλ…: STL(Standard Template Library). C++ ν‘œμ€€ 라이브러리의 ν•΅μ‹¬μœΌλ‘œ, μ»¨ν…Œμ΄λ„ˆ(Container), μ•Œκ³ λ¦¬μ¦˜(Algorithm), 그리고 이 λ‘˜μ„ μ—°κ²°ν•˜λŠ” 반볡자(Iterator)의 μ„Έ μš”μ†Œλ‘œ κ΅¬μ„±λœλ‹€. STL의 μœ„λŒ€ν•¨μ€ λ°˜λ³΅μžλΌλŠ” ν†΅μΌλœ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해, μ–΄λ–€ μ»¨ν…Œμ΄λ„ˆλΌλ„ μ–΄λ–€ μ•Œκ³ λ¦¬μ¦˜κ³Ό ν•¨κ»˜ λ™μž‘ν•  수 μžˆλ„λ‘ μ„€κ³„λ˜μ—ˆλ‹€λŠ” 점에 μžˆλ‹€. 신세계…! 객체 μ§€ν–₯ μ–Έμ–΄κ°€ μ™œ κ·Έλ ‡κ²Œ μ€‘μš”ν•œμ§€(…) 이 λͺ¨λ“ˆμ„ κΈ°μ€€μœΌλ‘œ 정말 많이 κΉ¨λ‹¬μ•˜μ—ˆλ‹€.
  • μ£Όμš” 과제: vector, list, map λ“± λ‹€μ–‘ν•œ μ»¨ν…Œμ΄λ„ˆμ˜ λ‚΄λΆ€ ꡬ쑰와 μ‹œκ°„ λ³΅μž‘λ„λ₯Ό μ΄ν•΄ν•˜κ³ , 각 상황에 λ§žλŠ” 졜적의 μ»¨ν…Œμ΄λ„ˆλ₯Ό μ„ νƒν•˜λŠ” λŠ₯λ ₯을 κΈ°λ₯Έλ‹€.

✨ λŒ€μž₯정을 마치며

C++ Module 00λΆ€ν„° 08κΉŒμ§€μ˜ 여정은 C++λΌλŠ” μ–Έμ–΄λ₯Ό 절차적, 객체 μ§€ν–₯적, 그리고 μ œλ„€λ¦­ ν”„λ‘œκ·Έλž˜λ°μ˜ κ΄€μ μ—μ„œ μž…μ²΄μ μœΌλ‘œ μ΄ν•΄ν•˜κ²Œ λ§Œλ“  심도 μžˆλŠ” ν›ˆλ ¨ κ³Όμ •μ΄μ—ˆλ‹€. 각 λͺ¨λ“ˆμ€ λ³΅μž‘ν•œ μ†Œν”„νŠΈμ›¨μ–΄λ₯Ό κ΅¬μΆ•ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ 각기 λ‹€λ₯Έ μ’…λ₯˜μ˜ β€˜λ¬΄κΈ°β€™λ₯Ό μ œκ³΅ν–ˆλ‹€. 이 κ²½ν—˜μ€ λ‹¨μˆœνžˆ C++ μ–Έμ–΄ μžμ²΄μ— λŒ€ν•œ μˆ™λ ¨λ„λ₯Ό λ„˜μ–΄, 문제의 λ³Έμ§ˆμ„ νŒŒμ•…ν•˜κ³  그에 κ°€μž₯ μ ν•©ν•œ ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μ„ μ„ νƒν•˜μ—¬ μ½”λ“œλ₯Ό κ΅¬μ‘°ν™”ν•˜λŠ” μ†Œν”„νŠΈμ›¨μ–΄ μ„€κ³„μžλ‘œμ„œμ˜ μ—­λŸ‰μ„ κΈΈλŸ¬μ£Όμ—ˆλ‹€.