Search

CPP Module 04

Created
2021/10/10
tag
42μ„œμšΈ
42Seoul
CPP Module
All of C++98

Subjects

1. ex00 (Polymorphism)

Compiletime Polymorphism & Runtime Polymorphism

Module 04의 μ‹œμž‘ 챕터 이름인 PolymorphismμœΌλ‘œλΆ€ν„° 미루어 보아 이번 μ„œλΈŒμ νŠΈμ˜ μ£Ό ν•™μŠ΅ λͺ©ν‘œλŠ” λ‹€ν˜•μ„±μ— λŒ€ν•œ μ •ν™•ν•œ 이해λ₯Ό ν•˜λŠ” 것이닀. λ‹€ν˜•μ„±μ€ λ‹¨μˆœν•˜κ²Œ λ³΄μ•˜μ„ λ•ŒλŠ” μƒμ†λ§ŒμœΌλ‘œ λ‹€ν˜•μ„±μ„ 이룬 κ²ƒμœΌλ‘œ 생각할 수 μžˆμœΌλ‚˜, λ‹€ν˜•μ„±μ„ 이루기 μœ„ν•΄μ„  상속 κ΅¬μ‘°μ—μ„œλ„ λͺ‡ 가지 μž‘μ—…μ„ λ§Œμ‘±ν•΄μ•Ό ν•œλ‹€. 이λ₯Ό 컴파일 νƒ€μž„κ³Ό 런 νƒ€μž„μœΌλ‘œ λ‚˜λˆ„μ–΄ 2가지 κ΄€μ μ—μ„œ 이해할 수 μžˆλ‹€.
컴파일 νƒ€μž„μ—μ„œλŠ” 상속 관계에 μžˆλŠ” ν΄λž˜μŠ€λ“€μ˜ ν•¨μˆ˜μ™€ μ—°μ‚°μžμ˜ Overloading듀이 적절히 이뀄져아 ν•˜κ³ , 런 νƒ€μž„μ—μ„œλŠ” virtual의 μ μ ˆν•œ Overriding 톡해 상속 관계에 μžˆλŠ” ν΄λž˜μŠ€λ“€μ΄ νƒ€μž…μ— λ§žλŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  수 μžˆμ–΄μ•Ό ν•œλ‹€. μœ„μ˜ 사진은 GeeksforGeeks의 자료인데, λ‹€ν˜•μ„± λ§Œμ‘±μ„ μœ„ν•œ 쑰건듀을 λͺ…ν™•ν•˜κ²Œ 이해할 수 μžˆλ‹€.
Overloading의 경우, μ—¬λŸ¬ μ‹œκ·Έλ‹ˆμ²˜λ‘œ κ΅¬μ„±λœ ν•¨μˆ˜λ“€ 쀑 μ–΄λŠ ν•¨μˆ˜λ₯Ό κ³ λ₯Ό 것인지 컴파일러의 κ·œμΉ™μ— μ˜ν•΄μ„œ 컴파일 νƒ€μž„μ— κ²°μ •λœλ‹€. Overriding은 Overloadingκ³Ό 달리 컴파일 νƒ€μž„μ— μ–΄λŠ ν•¨μˆ˜λ₯Ό κ³ λ₯Ό 것인지 κ²°μ • μ§“λŠ” 것이 μ•„λ‹ˆλΌ, 런 νƒ€μž„μ— vTable에 μœ μ§€λ˜κ³  μžˆλŠ” virtual둜 λͺ…μ‹œλœ ν•¨μˆ˜μ— λŒ€ν•΄ μžμ‹ μ˜ νƒ€μž…μ„ ν™•μΈν•˜λ©΄μ„œ μ μ ˆν•œ ν•¨μˆ˜λ₯Ό κ²°μ • μ§“λŠ”λ‹€. 이 λ•Œλ¬Έμ— Overloading - 컴파일 νƒ€μž„, Overriding - 런 νƒ€μž„μœΌλ‘œ κ΅¬λΆ„λœλ‹€. (Overriding의 ν˜ΈμΆœμ— λŒ€ν•œ ꡬ뢄이 런 νƒ€μž„μ— μ΄λ€„μ§„λ‹€λŠ” 것이지, Overriding을 μœ„ν•΄ μž‘μ„±ν•œ μ½”λ“œλŠ” λ‹Ήμ—°νžˆ 컴파일 νƒ€μž„μ— 이뀄진닀.)
특히 Overriding에 λŒ€ν•΄μ„œ virtual ν‚€μ›Œλ“œλŠ” Module 03μ—μ„œ ν•™μŠ΅ν–ˆκΈ° λ•Œλ¬Έμ—, Module 03μ—μ„œ ν–ˆλ˜ κ²ƒμ²˜λŸΌ μž‘μ„±μ„ μž˜ν•΄μ£Όλ©΄ μ—… μΊμŠ€νŒ…μ—λ„ 문제 없이 λ‹€ν˜•μ„±μ„ μœ μ§€ν•˜λŠ” 것을 확인할 수 μžˆλ‹€. μ§€κΈˆ μ–ΈκΈ‰λœ 뢀뢄이 이해가 잘 μ•ˆλœλ‹€λ©΄, λ°˜λ“œμ‹œ Module 03 글을 λ‹€μ‹œ μ°Έκ³ ν•˜μž.

Wrong Class

WrongAnimal ν΄λž˜μŠ€μ™€ WrongCat ν΄λž˜μŠ€λŠ” μ •μƒμ μœΌλ‘œ virtual ν‚€μ›Œλ“œλ₯Ό Overriding ν•œ ν΄λž˜μŠ€λ“€κ³Ό 비ꡐλ₯Ό μœ„ν•΄ virtual ν‚€μ›Œλ“œ 없이 Overridingν•˜μ—¬ μž‘μ„±ν•˜λ„λ‘ ν•œλ‹€. 이 λ•Œ Animal 클래슀둜 λ‹€ν˜•μ„±μ„ μ΄λ£¨λŠ” 객체와 WrongAnimal 클래슀둜 λ‹€ν˜•μ„±μ„ μ΄λ£¨λŠ” 객체 κ°„ μ—… μΊμŠ€νŒ…λœ ν¬μΈν„°λ‘œ 확인을 해보면, WrongAnimal 클래슀의 κ°μ²΄λŠ” μžμ‹ μ˜ νƒ€μž…μœΌλ‘œ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 것이 μ•„λ‹ˆλΌ 항상 WrongAnimal 클래슀의 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ €λŠ” 것을 λ³Ό 수 μžˆλ‹€. 이와 같은 κ²°κ³ΌλŠ” Module 03μ—μ„œ virtual ν‚€μ›Œλ“œλ₯Ό λ‹€λ£¨μ—ˆμ„ λ•Œ μ˜ˆμΈ‘ν•œ 결과와 κ°™λ‹€.
λ‹€μ‹œ ν•œ 번 μ˜¬λ°”λ₯Έ λ‹€ν˜•μ„±μ„ μœ„ν•΄ Overriding 뢀뢄을 짚자면, 기반 ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜ ν•˜λ €λŠ” ν•¨μˆ˜λŠ” virtual둜 λͺ…μ‹œν•΄μ•Ό ν•˜κ³ , νŒŒμƒ 클래슀의 μ†Œλ©ΈμžλŠ” virtual둜 λͺ…μ‹œν•΄μ•Ό ν•œλ‹€.

2. ex01 (I don’t want to set the world on fire)

Destructor

기쑴에 μ™„μ„±ν•΄λ‘” ν΄λž˜μŠ€λ“€μ—κ²ŒλŠ” λ³„λ„μ˜ ν¬μΈν„°λ‘œ μ •μ˜λœ 멀버 λ³€μˆ˜κ°€ μ—†μ—ˆλ‹€. 즉, 클래슀λ₯Ό 객체둜 μ΄μš©ν•  λ•ŒλŠ” 객체 자체의 자유 κ³΅κ°„μœΌλ‘œλΆ€ν„° ν• λ‹Ή μ—¬λΆ€λ§Œμ„ μ œμ™Έν•˜λ©΄ 객체의 μ†Œλ©Έκ³Ό ν•¨κ»˜ 내뢀에 μœ μ§€ 쀑인 λ©”λͺ¨λ¦¬λ“€μ€ μ •μƒμ μœΌλ‘œ λ°˜ν™˜λœλ‹€. ν•˜μ§€λ§Œ 클래슀 내에 ν¬μΈν„°λ‘œ μ •μ˜ν•œ 멀버 λ³€μˆ˜κ°€ 있고, 이 포인터λ₯Ό 자유 κ³΅κ°„μ—μ„œ ν• λ‹Ή 받은 λ©”λͺ¨λ¦¬λ₯Ό μ°Έμ‘°ν•˜λ„λ‘ μ΄μš©ν•œλ‹€λ©΄ λ‹¨μˆœνžˆ μ†Œλ©Έμž 호좜만으둜 자유 κ³΅κ°„μ˜ λ©”λͺ¨λ¦¬λŠ” λ°˜ν™˜λ˜μ§€ μ•ŠλŠ”λ‹€. ν•΄λ‹Ή κ²½μš°μ—λŠ” 자유 κ³΅κ°„μ˜ λ©”λͺ¨λ¦¬λŠ” λ°˜ν™˜λ˜μ§€ μ•ŠλŠ”λ°, μ†Œλ©Έμž 호좜 λ•Œλ¬Έμ— 포인터 μžμ²΄λŠ” μ΄μš©ν•  수 μ—†κ²Œ λ˜λ―€λ‘œ λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ‘œ 이어진닀. λ”°λΌμ„œ 클래슀 내에 멀버 λ³€μˆ˜λ₯Ό ν¬μΈν„°λ‘œ μ„ μ–Έν•΄λ‘” 것이 μžˆλ‹€λ©΄, λ°˜λ“œμ‹œ 포인터에 ν• λ‹Ήλœ 자유 κ³΅κ°„μ˜ λ©”λͺ¨λ¦¬λ₯Ό 적절히 λ°˜ν™˜ν•  수 μžˆλ„λ‘ 신경써야 ν•œλ‹€.
λ¬Όλ‘  포인터에 자유 κ³΅κ°„μœΌλ‘œλΆ€ν„° ν• λ‹Ή 받은 λ©”λͺ¨λ¦¬λ₯Ό μ°Έμ‘°ν•˜λ„λ‘ 할당해두지 μ•Šμ•˜λ‹€λ©΄, 멀버 λ³€μˆ˜λ‘œ 포인터λ₯Ό 둬도 λ©”λͺ¨λ¦¬λ“€μ€ 객체의 μ†Œλ©Έμž 호좜과 ν•¨κ»˜ μ •μƒμ μœΌλ‘œ λ°˜ν™˜λœλ‹€. ν•˜μ§€λ§Œ 일반적으둜 멀버 λ³€μˆ˜λ‘œ 포인터λ₯Ό λ‘λŠ” μ΄μœ λŠ” 자유 κ³΅κ°„μœΌλ‘œλΆ€ν„° λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ή λ°›μ•„ μ΄μš©ν•˜κΈ° μœ„ν•¨μ΄λ―€λ‘œ, μœ„μ—μ„œλŠ” 이 κ²½μš°μ— λŒ€ν•΄μ„œ μ„€λͺ…ν•œ 것이닀.
μ„œλΈŒμ νŠΈμ—μ„œλŠ” Brain 클래슀λ₯Ό Cat ν΄λž˜μŠ€μ™€ Dog ν΄λž˜μŠ€μ— ν¬μΈν„°λ‘œ μ‘΄μž¬ν•˜λ„λ‘ μš”κ΅¬ν–ˆμœΌλ―€λ‘œ, Cat ν΄λž˜μŠ€μ™€ Dog 클래슀의 μƒμ„±μžμ—μ„œ 할당받은 Brain 클래슀의 객체λ₯Ό 각 클래슀의 μ†Œλ©Έμžμ—μ„œ deleteλ₯Ό 톡해 적절히 ν•΄μ œν•˜λ„λ‘ κ΅¬ν˜„ν•˜λ©΄ λœλ‹€.

Deep Copy

포인터λ₯Ό 멀버 λ³€μˆ˜λ‘œ λ‘μ—ˆμ„ λ•Œ μ£Όμ˜ν•΄μ•Όν•  점은 μ†Œλ©Έμž 뿐만 μ•„λ‹ˆλΌ 볡사에도 μžˆλ‹€. 클래슀 λ‚΄μ—μ„œ 볡사λ₯Ό μ •μ˜ν•˜λŠ” κ²½μš°λŠ” operator=와 볡사 μƒμ„±μžκ°€ μžˆλ‹€. ν΄λž˜μŠ€μ—μ„œ μ œμ‹œλœ 2개의 ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄ μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ μžλ™μœΌλ‘œ κΈ°λ³Έ ν• λ‹Ή μ—°μ‚°μžμ™€ κΈ°λ³Έ 볡사 μƒμ„±μžκ°€ μƒμ„±λ˜λŠ”λ°, 이듀은 Shallow Copy (얕은 볡사)에 κΈ°μ΄ˆν•˜κ³  μžˆλ‹€. Shallow Copyκ°€ μ–΄λ–€ μ‹μœΌλ‘œ λ™μž‘ν•˜κΈ°μ— ν¬μΈν„°μ—μ„œ λ¬Έμ œκ°€ λ˜λŠ”μ§€ μ•„λž˜μ—μ„œ μ‚΄νŽ΄λ³΄μž.
class A { public: std::string _x; int _y; }; int main(void) { A a; A b; // Copy Every Member in b to a a = b; return (0); }
C++
Shallow CopyλŠ” 기본적으둜 각 νƒ€μž…μ˜ operator=에 κ·Όκ±°ν•˜μ—¬ λ™μž‘ν•œλ‹€. 즉, operator=와 볡사 μƒμ„±μžκ°€ μ •μ˜λ˜μ§€ μ•Šμ•„ μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ μƒμ„±λœ ν•¨μˆ˜λ“€μ€ ν΄λž˜μŠ€κ°€ λ³΄μœ ν•˜κ³  μžˆλŠ” λͺ¨λ“  멀버 λ³€μˆ˜μ— λŒ€ν•΄μ„œ λ‹¨μˆœ λŒ€μž…μ„ μ‹œλ„ν•œλ‹€. λ”°λΌμ„œ μœ„ μ½”λ“œμ—μ„œ a의 _xλŠ” b의 _x둜 a의 _yλŠ” b의 _y둜 λŒ€μž…μ΄ 이뀄진닀.
class A { public: std::string _x; int _y; int* _z; A(void) { _z = new int; } ~A(void) { delete _z; } }; int main(void) { A a; A b; // Copy Every Member in b to a a = b; return (0); }
C++
이 λ•Œ 만일 기쑴의 μ½”λ“œλ₯Ό μœ„μ™€ 같이 포인터λ₯Ό 멀버 λ³€μˆ˜λ‘œ 두도둝 μˆ˜μ •ν•˜κ³ , μƒμ„±μžμ—μ„œλŠ” ν•΄λ‹Ή 포인터에 동적 할당을 ν•˜λ„λ‘ λ§Œλ“€λ©΄ μ–΄λ–€ 일이 λ²Œμ–΄μ§ˆ 지 μ˜ˆμƒλ  것이닀. a의 _zκ°€ 기쑴에 μ°Έμ‘°ν•˜κ³  있던 자유 곡간은 b의 _zκ°€ μ°Έμ‘°ν•˜λŠ” 자유 곡간을 ν•¨κ»˜ μ°Έμ‘°ν•˜κ²Œ λ˜λ©΄μ„œ, 기쑴의 자유 곡간에 μ ‘κ·Όν•  수 μžˆλŠ” 포인터λ₯Ό μžƒμ–΄λ²„λ ΈκΈ° λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬ λˆ„μˆ˜κ°€ λ°œμƒν•œλ‹€.
class A { public: std::string _x; int _y; int* _z; A& operator=(const A& a) { _x = a._x; _y = a._y; if (_z) { delete _z; _z = NULL; } _z = new int; _z = a._z; } A(void) { _z = new int; } ~A(void) { delete _z; } A(const A& a) : _x(a._x), _y(a._y) { if (_z) { delete _z; _z = NULL; } _z = new int; _z = a._z; } }; int main(void) { A a; A b; // Copy Every Member in b to a a = b; return (0); }
C++
λ”°λΌμ„œ 이와 같이 포인터λ₯Ό 멀버 λ³€μˆ˜λ‘œ λ‘” κ²½μš°μ—λŠ” 볡사가 μ΄λ€„μ§€λŠ” λͺ¨λ“  ν•¨μˆ˜μ—μ„œ Deep Copyκ°€ μ΄λ€„μ§ˆ 수 μžˆλ„λ‘ ν•¨μˆ˜λ“€μ„ 직접 μ •μ˜ν•΄μ•Ό ν•œλ‹€.
이처럼 클래슀 내에 μ›μ‹œ 포인터λ₯Ό λ‘λŠ” 것은 λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ„ λ¬Έμ œμ§€λ§Œ, 직접 μ •μ˜ν•  μ½”λ“œλ„ λŠ˜μ–΄λ‚œλ‹€. 특히 클래슀 외에도 λ‹¨μˆœνžˆ μ›μ‹œ 포인터λ₯Ό μ΄μš©ν•˜λŠ” κ²½μš°μ—λŠ” μ—λŸ¬κ°€ λ°œμƒν–ˆμ„ λ•Œ try-catch둜 μž‘μ•„λ‚΄λ”λΌλ„ 포인터가 μ°Έμ‘°ν•˜λŠ” 곡간에 λŒ€ν•΄μ„œλŠ” ν•΄μ œκ°€ λ˜μ§€ μ•ŠμœΌλ―€λ‘œ μ—¬λŸ¬λͺ¨λ‘œ λ©”λͺ¨λ¦¬ λˆ„μˆ˜μ— μ·¨μ•½ν•˜λ‹€. (try-catch λ‚΄μ—μ„œ μž‘μ„±λœ κ΅¬λ¬Έμ—μ„œ μ—λŸ¬κ°€ λ°œμƒν–ˆμ„ λ•ŒλŠ” Stack Unwidingμ΄λΌλŠ” μž‘μ—…μ„ 톡해 κ°μ²΄λ“€μ˜ μ†Œλ©Έμžλ“€μ΄ μžλ™μœΌλ‘œ ν˜ΈμΆœλ˜λŠ”λ°, μ›μ‹œ ν¬μΈν„°λŠ” 객체가 μ•„λ‹ˆλ―€λ‘œ λ©”λͺ¨λ¦¬ ν•΄μ œλ₯Ό 보μž₯받을 수 μ—†λ‹€.) λ”°λΌμ„œ Modern C++μ—μ„œλŠ” 이와 같은 λ¬Έμ œλ“€μ„ ν•΄κ²°ν•˜κΈ° μœ„ν•΄ 슀마트 포인터가 λ„μž…λ˜μ–΄, μ›μ‹œ 포인터λ₯Ό 객체둜 κ°μ‹Έμ„œ μ΄μš©ν•˜κ²Œ λœλ‹€. λ¬Όλ‘  슀마트 포인터가 μ›μ‹œ 포인터λ₯Ό μ™„μ „νžˆ λŒ€μ²΄ν•  수 μžˆλŠ” 것은 μ•„λ‹ˆμ§€λ§Œ, μ†Œλ©Έμžμ™€ Deep Copy의 λ¬Έμ œλŠ” 극볡할 수 μžˆλ‹€. Modern C++을 μ΄μš©ν•  생각이라면 슀마트 포인터에 λŒ€ν•΄μ„œλ„ λ°˜λ“œμ‹œ ν•™μŠ΅ν•˜κΈΈ λ°”λž€λ‹€.

Additional Function

Module 01μ—μ„œ Zombie 클래슀의 멀버 λ³€μˆ˜ _name을 λ§Œλ“€κΈ° μœ„ν•΄ μ΄μš©ν•œ Random 클래슀λ₯Ό λ‹€μ‹œ μ •μ˜ν–ˆλ‹€. ν•΄λ‹Ή ν•¨μˆ˜λŠ” Brain 클래슀의 _idea λ°°μ—΄μ˜ μš”μ†Œλ‘œ ν• λ‹Ήν•˜κΈ° μœ„ν•œ λ¬Έμžμ—΄μ„ λ§Œλ“ λ‹€. κ·Έ 외에도 _idea λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μ„€μ •ν•˜κ³  κ°–κ³ μ˜¬ 수 μžˆλ„λ‘, setIdea와 getIdea ν•¨μˆ˜λ₯Ό 적절히 μ •μ˜ν•΄μ£Όλ©΄, 쑰금 더 μ›ν™œν•œ λ™μž‘μ΄ μ΄λ€„μ§€λŠ” main ν•¨μˆ˜λ₯Ό ꡬ성할 수 μžˆλ‹€.

3. ex02 (abstract class)

Pure Virtual Function & Abstract Class

기쑴에 μ •μ˜ν•΄λ‘” Animal ν΄λž˜μŠ€κ°€ μ—… μΊμŠ€νŒ…μ„ μœ„ν•΄ κ³΅ν†΅μ˜ ν¬μΈν„°λ‘œ 이용될 μˆ˜λŠ” μžˆμ§€λ§Œ, Animal 클래슀 자체λ₯Ό 객체둜 μ΄μš©ν•˜μ§€λŠ” μ•ŠκΈ° λ•Œλ¬Έμ— 이에 λŒ€ν•œ μ μ ˆν•œ μˆ˜μ •μ„ ν•˜λŠ” 것이 ex02의 λͺ©ν‘œμ΄λ‹€. μ΄λŠ” Pure Virtual Function (순수 가상 ν•¨μˆ˜)λ₯Ό μ΄μš©ν•˜μ—¬ 달성할 수 μžˆλ‹€.
class A { private: // ... implementation public: virtual void pvf(void) const = 0; // ... implementation };
C++
Pure Virtual Functionμ΄λž€ μœ„ μ½”λ“œμ—μ„œ λ³Ό 수 μžˆλ“―μ΄, 클래슀 λ‚΄μ—μ„œ virtual둜 λͺ…μ‹œλœ ν•¨μˆ˜λ“€ μ€‘μ—μ„œ 0이 ν• λ‹Ήλœ ν•¨μˆ˜λ₯Ό μ˜λ―Έν•œλ‹€. 0을 ν• λ‹Ήν•œ μ˜λ―ΈλŠ” ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜μ§€ μ•Šκ² λ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€. ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜μ§€ μ•Šκ² λ‹€λΌλŠ” 사싀이 μ‹œμ‚¬ν•˜λŠ” 점은 2가지가 μžˆλ‹€. 첫 μ§ΈλŠ” μ •μ˜λ˜μ§€ μ•Šμ€ ν•¨μˆ˜κ°€ ν¬ν•¨λœ κ°μ²΄λŠ” λ‹€ν˜•μ„±μ„ μœ„ν•œ νŒŒμƒ ν΄λž˜μŠ€μ—μ„œμ˜ 생성을 μ œμ™Έν•˜κ³ λŠ” 직접 생성이 λΆˆκ°€λŠ₯ν•˜λ‹€λŠ” 점이닀. λ‘˜ μ§ΈλŠ” ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό νŒŒμƒ ν΄λž˜μŠ€μ—μ„œ Overriding ν•˜μ§€ μ•ŠμœΌλ©΄ μ—¬μ „νžˆ μ •μ˜λ˜μ§€ μ•Šμ€ ν•¨μˆ˜κ°€ λ˜μ–΄ νŒŒμƒ 클래슀 μ—­μ‹œ 객체둜 λ§Œλ“€ 수 μ—†μœΌλ―€λ‘œ, νŒŒμƒ ν΄λž˜μŠ€μ—μ„œλŠ” λ°˜λ“œμ‹œ Pure Virtual Function을 μ •μ˜ν•΄μ•Ό ν•œλ‹€λŠ” 점이닀.
즉, Pure Virtual Function을 κ°–κ³  μžˆλŠ” ν΄λž˜μŠ€λŠ” νŒŒμƒ ν΄λž˜μŠ€μ—κ²Œ 청사진을 μ œκ³΅ν•˜λ©΄μ„œ, κ·Έ μžμ²΄λ‘œλŠ” 객체둜 μ΄μš©ν•  수 μ—†κΈ° λ•Œλ¬Έμ— μΌμ’…μ˜ Interface둜 λ™μž‘ν•œλ‹€. 이와 같은 클래슀λ₯Ό Abstract Class (좔상 클래슀)라고 λΆ€λ₯Έλ‹€.
#include <iostream> class A { private: virtual void something(void) = 0; }; class B : public A { public: void something(void) { std::cout << "hi" << std::endl; } }; int main(void) { B b; b.something(); return (0); }
C++
참고둜 Pure Virtual Function은 private μ˜μ—­μ— μžˆμ–΄λ„ νŒŒμƒ ν΄λž˜μŠ€μ—μ„œ Overriding이 κ°€λŠ₯ν•˜λ―€λ‘œ, μ–΄λŠ μ˜μ—­μ— μžˆμ–΄λ„ λ¬Έμ œκ°€ λ˜μ§€ μ•ŠλŠ”λ‹€. κ΅¬ν˜„ν•˜λ €λŠ” ν•¨μˆ˜μ˜ μ˜λ―Έμ— λ§žμΆ°μ„œ μ μ ˆν•œ μ˜μ—­μ— μœ„μΉ˜μ‹œν‚€κ³ , νŒŒμƒ ν΄λž˜μŠ€μ—μ„œλŠ” Pure Virtual Function을 적절히 Overridingλ₯Ό 해주도둝 ν•˜μž.

Orthodox Canonical Form of Abstract Class?

#include <iostream> class A { virtual void something(void) = 0; }; int main(void) { A a; return (0); }
C++
좔상 ν΄λž˜μŠ€λŠ” Interface둜 λ™μž‘ν•˜κΈ° λ•Œλ¬Έμ— κ·Έ 자체λ₯Ό 객체둜 λ§Œλ“€ 수 μ—†λ‹€κ³  ν–ˆλ‹€. λ”°λΌμ„œ μœ„ ꡬ문은 컴파일 λ˜μ§€ μ•ŠμœΌλ©°, μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” 것을 λ³Ό 수 μžˆλ‹€. 이 λ•Œ 객체둜 λ§Œλ“€ 수 μ—†λ‹€λŠ” μ˜€ν•΄ λ•Œλ¬Έμ— Orthdox Canonical Form을 μž‘μ„±ν•˜λŠ” 것이 μ˜λ―Έκ°€ μžˆλŠ”μ§€ 의문이 λ“€ 수 μžˆλ‹€. ν•˜μ§€λ§Œ 좔상 ν΄λž˜μŠ€λŠ” νŠΉμ • κ²½μš°μ— 객체화 될 수 있으며, μƒμ„±μžμ™€ μ†Œλ©Έμžλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.
좔상 ν΄λž˜μŠ€κ°€ 객체화 될 수 μžˆλŠ” κ²½μš°λŠ” νŒŒμƒ 클래슀λ₯Ό 생성할 λ•Œμ΄λ‹€. μ‹€μ œλ‘œ 좔상 클래슀 λ‚΄μ—λŠ” Pure Virtual Function만 μ‘΄μž¬ν•  수 μžˆλŠ” 것이 μ•„λ‹ˆλΌ, μ‹€μ œλ‘œ 호좜될 수 μžˆλ„λ‘ μ •μ˜λœ ν•¨μˆ˜λ₯Ό ν¬ν•¨ν•˜μ—¬ 멀버 λ³€μˆ˜λ“€λ„ κ°–κ³  μžˆμ„ 수 μžˆλ‹€. λ”°λΌμ„œ 좔상 클래슀λ₯Ό μƒμ†ν•˜μ—¬ μƒμ„±λœ νŒŒμƒ ν΄λž˜μŠ€μ—μ„œλŠ” λ‹Ήμ—°νžˆ 좔상 클래슀의 멀버 λ³€μˆ˜ 뿐만 μ•„λ‹ˆλΌ μ •μ˜λœ ν•¨μˆ˜λ“€λ„ ν˜ΈμΆœν•  수 μžˆλ‹€. 이 λ•Œ 만일 좔상 ν΄λž˜μŠ€κ°€ 객체둜써 νŒŒμƒ 클래슀의 λ©”λͺ¨λ¦¬ λ ˆμ΄μ•„μ›ƒμ— ν•¨κ»˜ μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄, νŒŒμƒ ν΄λž˜μŠ€μ—μ„œλŠ” 좔상 ν΄λž˜μŠ€μ— μ •μ˜λœ μ—¬λŸ¬ λ³€μˆ˜μ™€ ν•¨μˆ˜λ₯Ό μ΄μš©ν•  수 μ—†λ‹€.
#include <iostream> class A { private: virtual void something(void) = 0; public: A(void) { std::cout << "A Default Constructor" << std::endl; } ~A(void) { std::cout << "A Destructor" << std::endl; } }; class B : public A { public: void something(void) { std::cout << "hi" << std::endl; } B(void) : A() { std::cout << "B Default Constructor" << std::endl; } ~B(void) { std::cout << "B Destructor" << std::endl; } }; int main(void) { B b; b.something(); return (0); }
C++
이λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄ μœ„μ™€ 같은 μ½”λ“œλ₯Ό μž‘μ„±ν•˜μ—¬ 싀행해보면, B 클래슀λ₯Ό 객체둜 λ§Œλ“€κΈ° μœ„ν•΄ A 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜λŠ” 것을 λ³Ό 수 있고 λ§ˆμ§€λ§‰μ—” μ†Œλ©Έμžλ„ ν˜ΈμΆœλ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€. 즉, B 클래슀의 μƒμ„±μžμ—μ„œλŠ” 상황에 λ§žλŠ” A 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•  수 μžˆλ„λ‘ κ΅¬ν˜„ν•  수 μžˆμœΌλ―€λ‘œ, A ν΄λž˜μŠ€μ—μ„œ ν•„μš”ν•œ μƒμ„±μžλ₯Ό ν¬ν•¨ν•˜μ—¬ Orthodox Canonical Form을 μ΅œλŒ€ν•œ μœ μ§€ν•  ν•„μš”κ°€ μžˆλ‹€.

4. ex03 (Interface & recap)

Figure Out

λ§ˆμ§€λ§‰ λ¬Έμ œλŠ” ex00 - ex02κΉŒμ§€ 주어진 문제λ₯Ό μž¬ν™œμš©ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, μ΄μ œκΉŒμ§€ ν•™μŠ΅ν•œ λ‹€ν˜•μ„±μ„ μœ„ν•œ μ˜¬λ°”λ₯Έ Overloading, Overriding 그리고 좔상 클래슀λ₯Ό ν™œμš©ν•˜μ—¬ μ μ ˆν•œ OOP ν”„λ‘œκ·Έλž˜λ°μ„ ν•΄λ³΄λŠ” 것이닀. 문제λ₯Ό 보면 κ½€λ‚˜ κ΅¬ν˜„ν•  μš”μ†Œλ“€μ΄ λ§Žμ€λ°, ν•˜λ‚˜ ν•˜λ‚˜ μ‚΄νŽ΄λ³΄λ©΄ κ·Έλ ‡κ²Œ μ–΄λ ΅μ§€λŠ” μ•Šλ‹€.
β€’
AMateria β†’ Interface of Cure & Ice
β€’
Cure
β€’
Ice
β€’
ICharacter β†’ Interface of Character
β€’
Character
β€’
IMateriaSource β†’ Interface of MateriaSource
β€’
MateriaSource
μ •μ˜ν•  ν΄λž˜μŠ€λŠ” λͺ¨λ‘ 7개이며, 이듀 쀑 ICharacter와 IMateriaSourceλŠ” μ„œλΈŒμ νŠΈμ— μ •ν™•ν•œ μ •μ˜κ°€ μžˆλ‹€. 특히 두 ν΄λž˜μŠ€λŠ” μ†Œλ©Έμžμ— λŒ€ν•΄μ„  클래슀 λ‚΄μ—μ„œ 직접 μ •μ˜λ˜μ–΄ 있고, λ‚˜λ¨Έμ§€ ν•¨μˆ˜λŠ” Pure Virtual Function으둜 μ„ μ–Έλ˜μ–΄ 있기 λ•Œλ¬Έμ— 좔가적인 μ •μ˜κ°€ ν•„μš”ν•˜μ§€ μ•Šλ‹€. λ”°λΌμ„œ AMateria, Cure, Ice, Character, MateriaSource에 λŒ€ν•œ μ •μ˜λ§Œ 적절히 두면 λœλ‹€. 각 클래슀의 μ •μ˜λŠ” μ„œλΈŒμ νŠΈμ—μ„œ 주어진 λŒ€λ‘œ 꼼꼼히 μ§„ν–‰ν•˜λ©΄ 되고, 각 클래슀의 μš©λ„κ°€ 이해가 λ˜μ§€ μ•ŠλŠ”λ‹€λ©΄ μ•„λž˜λ₯Ό μ°Έκ³ ν•˜μž.
1.
μ‚¬μš©μžλŠ” Character둜 λ‚˜νƒ€λ‚˜κ³ , 이듀은 Cure와 Ice 같은 AMateriaλ₯Ό Interface둜 ν•˜λŠ” λ¬Όμ§ˆλ“€μ„ μ†Œμ§€ν•  수 μžˆλ‹€. 이 λ•Œ CharacterλŠ” AMateria에 λŒ€ν•΄ equip, unequip, useλΌλŠ” μƒν˜Έμž‘μš©μ„ λ§Œλ“€μ–΄λ‚Ό 수 μžˆλ‹€.
2.
Ice, Cure와 같은 AMateriaλ₯Ό Interface둜 ν•˜λŠ” λ¬Όμ§ˆλ“€μ€ λ‹¨μˆœνžˆ 생성해낼 수 μžˆλŠ” 것은 μ•„λ‹ˆλ‹€. ν•΄λ‹Ή λ¬Όμ§ˆλ“€μ„ μƒμ„±ν•˜κΈ° μœ„ν•΄μ„  IMateriaSourceλ₯Ό Interface둜 ν•˜λŠ” MateriaSourceλ₯Ό μ΄μš©ν•΄μ•Ό ν•œλ‹€. 그리고 MateriaSourceλ₯Ό μ΄μš©ν•˜μ—¬ λ¬Όμ§ˆμ„ μƒμ„±ν•˜κΈ° μ „μ—λŠ” μ„ ν–‰μ μœΌλ‘œ λ¬Όμ§ˆμ— λŒ€ν•œ ν•™μŠ΅μ΄ ν•„μš”ν•˜λ‹€. 이λ₯Ό μœ„ν•œ μƒν˜Έμž‘μš©μœΌλ‘œλŠ” MateriaSource의 learnMateria와 createMateriaκ°€ μžˆλ‹€.

Don't Mistake

이번 ν’€μ΄μ—μ„œλŠ” μ›μ‹œ 포인터λ₯Ό ν™œμš©ν•  일이 ꡉμž₯히 λ§Žλ‹€. CharacterλŠ” AMateria*λ₯Ό 4κ°œκΉŒμ§€ μ΄μš©ν•  수 있으며, 생성할 수 μžˆλŠ” λ¬Όμ§ˆμ€ MateriaSourceμ—μ„œ AMateria*둜 4κ°œκΉŒμ§€ κ΄€λ¦¬λœλ‹€. 즉, λ‹€λ₯Έ ν΄λž˜μŠ€λ“€μ€ λͺ°λΌλ„ Character와 MateriaSource에 λŒ€ν•΄μ„  Deep Copy 뿐만 μ•„λ‹ˆλΌ, μ†Œλ©Έμžμ— λŒ€ν•΄μ„œλ„ 맀우 신경써야 λ¬Έμ œκ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.
Deep Copy와 μ†Œλ©Έμž λͺ¨λ‘ 기쑴에 κ°–κ³  있던 AMateriaλ₯Ό λͺ¨λ‘ ν•΄μ œν•  ν•„μš”κ°€ μžˆλ‹€κ³  λ‚˜μ™€ μžˆλŠ”λ°, C μ–Έμ–΄μ—μ„œ 동적 할당을 μž‘μ„±ν–ˆμ„ λ•Œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 이쀑 ν•΄μ œλ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄μ„œ λ©”λͺ¨λ¦¬ ν•΄μ œ μ‹œ Defensive-Style을 κ³ μˆ˜ν•  수 μžˆλ„λ‘ ν•œλ‹€. λ©”λͺ¨λ¦¬λ₯Ό 잘 ν•΄μ œ ν–ˆλ‹€λ©΄, Deep CopyλŠ” 객체의 AMateriaκ°€ κ°–κ³  μžˆλŠ” clone ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ μƒˆλ‘œμš΄ AMateriaλ₯Ό κΈ°μ‘΄ 객체의 μš”μ†Œλ‘œ 두도둝 κΉ”λ”ν•˜κ²Œ μž‘μ„±ν•  수 μžˆλ‹€.
μ—¬κΈ°μ„œ λ§ν•˜λŠ” Defensive-Style은 λ©”λͺ¨λ¦¬ ν•΄μ œ 이후에 ν•΄λ‹Ή λ©”λͺ¨λ¦¬λ₯Ό μ°Έμ‘°ν•˜κ³  있던 포인터에 NULL을 ν• λ‹Ήν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€.
λ˜ν•œ 두 ν΄λž˜μŠ€μ— λŒ€ν•΄ μƒμ„±μžλ‘œ 객체λ₯Ό λ§Œλ“€λ©΄, AMateria* λ°°μ—΄μ˜ μš”μ†Œλ“€μ„ NULL둜 μ΄ˆκΈ°ν™”λ₯Ό ν•˜λŠ” 것이 μ•ˆμ „ν•˜λ‹€. μ΄λ ‡κ²Œ ν•΄μ•Ό equip, unequip, use, learnMateria, createMateria λ“±μœΌλ‘œ AMateria*λ₯Ό μ‘°μž‘ν•  λ•Œ μ˜ˆμ™Έ μΌ€μ΄μŠ€λ“€μ„ 잘 κ±ΈλŸ¬λ‚Ό 수 μžˆλ‹€. C μ–Έμ–΄μ—μ„œ ν•™μŠ΅ν–ˆλ˜ 각 ν•¨μˆ˜λ“€μ˜ NULL μ—¬λΆ€ 확인을 μžŠμ§€ μ•Šλ„λ‘ ν•˜μž.

5. Code of Jseo