C++

κ°€μƒν•¨μˆ˜(virtual function), ν•¨μˆ˜ μž¬μ •μ˜ (function redefine)

kanghou 2022. 11. 25. 03:57

🎈 가상 ν•¨μˆ˜(virtual function)

가상 ν•¨μˆ˜λŠ” 순수 가상 ν•¨μˆ˜(pure virtual class)와 일반 가상 ν•¨μˆ˜(virtual class)둜 κ΅¬λΆ„λ˜μ–΄ μ‚¬μš©λœλ‹€. λ‘˜ λ‹€ 가상 ν•¨μˆ˜ 이기 λ•Œλ¬Έμ— κΈ°λ³Έ κ°œλ…μ€ κ°™κ³  μ‚¬μš© λ°©λ²•μ˜ 차이만 μžˆλ‹€. 가상 ν•¨μˆ˜μ˜ κΈ°λ³Έ κ°œλ…μ€ λ‹€μŒκ³Ό κ°™λ‹€.

κ°€μƒν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜κ²Œ 되면 λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ μ„ μ–Έν•œ ν•¨μˆ˜κ°€ μžμ‹ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜ 될 수 μžˆλ‹€κ³  μ•Œλ €μ£Όκ²Œ λ˜μ–΄ κΈ°λ³Έ 클래슀 νƒ€μž…μ˜ 포인터 λ˜λŠ” μ°Έμ‘°λ₯Ό 톡해 μžμ‹ 클래슀의 객체λ₯Ό μ°Έμ‘°ν•˜μ—¬ ν•΄λ‹Ή 객체에 λŒ€ν•œ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•  수 있게 λœλ‹€.

 

β–Ά μΌλ°˜ 가상 ν•¨μˆ˜(virtual function)λŠ” λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ μ„ μ–Έν•œ λ©”μ†Œλ“œλ₯Ό μžμ‹ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜ν•΄μ„œ μ‚¬μš©ν•΄λ„ λœλ‹€λŠ” κ°€λŠ₯성을 μ—΄μ–΄λ‘λŠ” 것이닀. μ•žμ˜ μ˜€λ²„λΌμ΄λ”©μ—μ„œ ν–ˆλ˜ κ²ƒμ²˜λŸΌ λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œλ„ ν•¨μˆ˜μ˜ κΈ°λŠ₯이 μ •μ˜λ˜μ–΄ 있고 ν•„μš”ν•˜λ‹€λ©΄ κΈ°λŠ₯을 ν™•μž₯ν•˜κ±°λ‚˜ λ³€κ²½ν•˜λŠ”λ° virtual ν‚€μ›Œλ“œλ₯Ό 톡해 포인터 νƒ€μž…μ΄ μ•„λ‹Œ μ°Έμ‘°ν•˜λŠ” 객체의 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ λΆ™μ΄κ²Œ λœλ‹€.

β–Ά μˆœμˆ˜ 가상 ν•¨μˆ˜(pure virtual function)λŠ” μžμ‹ ν΄λž˜μŠ€μ—μ„œ λ°˜λ“œμ‹œ μž¬μ •μ˜ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό λœ»ν•œλ‹€. λ”°λΌμ„œ λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ ν•¨μˆ˜μ˜ κΈ°λŠ₯이 μ •μ˜λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ©° μžμ‹ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄ μ‚¬μš©μ΄ λΆˆκ°€λŠ₯ν•˜λ‹€.

 

πŸŽ‡λ¬Έλ²•

class 클래슀λͺ…

{

    virtual 멀버 ν•¨μˆ˜μ˜ μ›ν˜•;          //일반 가상 ν•¨μˆ˜

    virtual 멀버 ν•¨μˆ˜μ˜ μ›ν˜• = 0;    //순수 가상 ν•¨μˆ˜

};

 

λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ virtual을 톡해 ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ μžμ‹ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜ν•œ ν•¨μˆ˜ λ˜ν•œ μžλ™μœΌλ‘œ virtual ν•¨μˆ˜κ°€ 되기 λ•Œλ¬Έμ— μžμ‹ ν΄λž˜μŠ€μ—μ„œ virtual을 μƒλž΅ν•΄λ„ λ˜μ§€λ§Œ 가상 ν•¨μˆ˜μž„μ„ λͺ…μ‹œν•˜κΈ° μœ„ν•΄ μžμ‹ ν΄λž˜μŠ€μ—μ„œλ„ virtual ν‚€μ›Œλ“œλ₯Ό λΆ™μ—¬μ£ΌλŠ” 것이 μ’‹λ‹€.  


🎈 가상 ν•¨μˆ˜μ˜ κ΅¬ν˜„ 원리

λͺ¨λ“  ν•¨μˆ˜λ₯Ό κ°€μƒν•¨μˆ˜λ‘œ λ§Œλ“€λ©΄ νŽΈν•  것 κ°™μ§€λ§Œ, 사싀 κ°€μƒν•¨μˆ˜λŠ” μ˜€λ²„ν—€λ“œκ°€ 크닀. μ™œλƒν•˜λ©΄ virtual ν•¨μˆ˜λŠ” λŸ°νƒ€μž„μ— μ–΄λ–€ ν•¨μˆ˜κ°€ μ‹€ν–‰ν• μ§€λ₯Ό κ²°μ •ν•˜λŠ” 동적 바인딩 방식이기 λ•Œλ¬Έμ΄λ‹€.

 

C++ μ»΄νŒŒμΌλŸ¬λŠ” 가상 ν•¨μˆ˜κ°€ ν•˜λ‚˜λΌλ„ μ‘΄μž¬ν•˜λŠ” ν΄λž˜μŠ€μ— λŒ€ν•΄ κ°€μƒ ν•¨μˆ˜ ν…Œμ΄λΈ”(virtual function table; vtable)을 μƒμ„±ν•œλ‹€. 

 

p의 경우, func1이 κ°€μƒν•¨μˆ˜μ΄λ―€λ‘œ, κ°€μƒν•¨μˆ˜ ν…Œμ΄λΈ”μ„ ν•œ 번 더 μ°Έμ‘°ν•˜μ—¬ Parent::func1()을 ν˜ΈμΆœν•˜κ²Œ 되고, c의 κ²½μš°μ—λ„ λ§ˆμ°¬κ°€μ§€λ‘œ κ°€μƒν•¨μˆ˜ ν…Œμ΄λΈ”μ„ μ°Έμ‘°ν•˜μ—¬ Child::func1()을 ν˜ΈμΆœν•˜κ²Œ λœλ‹€. μ΄λŠ” μ˜€λ²„ν—€λ“œκ°€ μΆ”κ°€λ˜λŠ” 것을 μ˜λ―Έν•˜λ―€λ‘œ, C++의 멀버 ν•¨μˆ˜λŠ” λ””ν΄νŠΈλ‘œ κ°€μƒν•¨μˆ˜κ°€ λ˜λ„λ‘ λ§Œλ“€μ–΄μ§€μ§€ μ•Šμ€ 것이닀.


πŸŽˆκ°€μƒ ν•¨μˆ˜μ™€ 순수 가상 ν•¨μˆ˜λ₯Ό μ˜ˆμ‹œ

λ‹€μŒκ³Ό 같이 Car ν΄λž˜μŠ€μ™€ SuperCar 클래슀λ₯Ό μ„ μ–Έν•˜κ³  Car 클래슀 νƒ€μž…μ˜ 포인터 λ³€μˆ˜μ— SuperCar 클래슀둜 λ§Œλ“  객체의 μ£Όμ†Œλ₯Ό λ‹΄μ•„μ£Όλ©΄ SuperCar의 Speed() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  것 κ°™μ§€λ§Œ κ·Έλ ‡μ§€ μ•Šκ³  포인터 νƒ€μž…μ— ν•΄λ‹Ήν•˜λŠ” 클래슀의 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 것을 확인할 수 μžˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ 가상 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€.


일반 가상 ν•¨μˆ˜λ₯Ό 톡해 SpeedλΌλŠ” ν•¨μˆ˜κ°€ μžμ‹ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜λ˜μ–΄ μ‚¬μš©λ  수 μžˆλ‹€κ³  μ•Œλ €μ£ΌκΈ° λ•Œλ¬Έμ— Car νƒ€μž…μ˜ 포인터 λ³€μˆ˜λ‘œ scar의 객체의 μ£Όμ†Œλ₯Ό λ‹΄μ•„ μ‚¬μš©ν•˜λ©΄ κ·Έλ•ŒλΆ€ν„° ν•΄λ‹Ή 객체의 λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•  수 있게 λœλ‹€.


λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ 순수 가상 ν•¨μˆ˜λ‘œ μ„ μ–Έλ˜μ–΄ 있기 λ•Œλ¬Έμ— μžμ‹ ν΄λž˜μŠ€μ—μ„œ ν•¨μˆ˜λ₯Ό μž¬μ •μ˜ ν•˜μ§€ μ•Šμ„ 경우 μ‚¬μš©ν• μˆ˜ μ—†λŠ” 것을 확인할 수 μžˆλ‹€.


μžμ‹ν΄λž˜μŠ€μ—μ„œ 순수 가상 ν•¨μˆ˜λ‘œ μ„ μ–Έλœ ν•¨μˆ˜λŠ” 무쑰건 μž¬μ •μ˜ν•˜μ—¬μ•Ό ν•˜λ©° 일반 가상 ν•¨μˆ˜μ™€ λ˜‘κ°™μ΄ Carνƒ€μž…μ˜ 포인터 λ³€μˆ˜λ‘œ μžμ‹ 객체λ₯Ό λ‹΄μ•„ μ‚¬μš©ν•  수 있게 λœλ‹€.

순수 가상 ν•¨μˆ˜μ™€ 일반 가상 ν•¨μˆ˜μ˜ κΈ°λŠ₯적인 μ°¨μ΄λŠ” μ—†μœΌλ©° μ„€κ³„ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ°μ— 맞게 κ³¨λΌμ„œ μ‚¬μš©ν•˜λ©΄ λœλ‹€.


🎈 ν•¨μˆ˜ μž¬μ •μ˜ (function redefine)

ν•¨μˆ˜λŠ” νŒŒμƒ ν΄λž˜μŠ€μ—μ„œ κΈ°λ³Έ ν΄λž˜μŠ€μ™€ λ™μΌν•œ ν˜•μ‹μ˜ ν•¨μˆ˜λ₯Ό μž¬μ •μ˜ν•˜μ—¬ μ‚¬μš©ν•˜λŠ” 것이닀.

 

λ‹€μŒκ³Ό 같이 CarκΈ°λ³Έ 클래슀λ₯Ό μƒμ†ν•œ νŒŒμƒ 클래슀 NomalCar,SuperCarλŠ”

Car의 멀버 ν•¨μˆ˜μΈ Speed()λ₯Ό μž¬μ •μ˜ν•˜μ—¬ κ΅¬ν˜„ν•˜μ˜€λ‹€. 


πŸŽ‡νŒŒμƒ 클래슀 포인터 -> νŒŒμƒ 클래슀 객체의 ν•¨μˆ˜ 호좜

νŒŒμƒ 클래슀 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” νŒŒμƒ 클래슀 ν¬μΈν„°λ‘œ 

μž¬μ •μ˜λœ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄, νŒŒμƒ ν΄λž˜μŠ€μ— μž‘μ„±λœ 멀버λ₯Ό 기본적으둜 ν˜ΈμΆœν•œλ‹€.

μ•„λž˜μ—μ„œ νŒŒμƒ 클래슀의 포인터 pt_car이 νŒŒμƒ 클래슀 객체 Aλ₯Ό 가리킬 λ•Œ Speed()λ₯Ό ν˜ΈμΆœν•˜λ©΄,

νŒŒμƒ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜λœ NomalCar의 멀버 Speed()κ°€ ν˜ΈμΆœλœλ‹€.

μž¬μ •μ˜ 되기 μ΄μ „μ˜, κΈ°λ³Έ 클래슀의 멀버λ₯Ό ν˜ΈμΆœν•˜λ €λ©΄ λ²”μœ„ μ§€μ • μ—°μ‚°μž(::)λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.


πŸŽ‡μ—…μΊμŠ€νŒ…μ„ ν†΅ν•œ κΈ°λ³Έ 클래슀의 포인터 -> νŒŒμƒ 클래슀 객체

μ—…μΊμŠ€νŒ…μ„ 톡해 κΈ°λ³Έ 클래슀의 ν¬μΈν„°λ‘œ νŒŒμƒ 클래슀의 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” 경우 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.

pCarλŠ” κΈ°λ³Έ ν΄λž˜μŠ€μ— λŒ€ν•œ ν¬μΈν„°μ΄λ―€λ‘œ, κΈ°λ³Έ 클래슀의 λ©€λ²„μ—λ§Œ μ ‘κ·Όν•  수 μžˆλ‹€.

λ”°λΌμ„œ Speed()λ₯Ό ν˜ΈμΆœν•˜λ©΄, κΈ°λ³Έ 클래슀 Car의 멀버 Speed()κ°€ ν˜ΈμΆœλœλ‹€.