Search

CPP Module 03

Created
2021/10/09
tag
42์„œ์šธ
42Seoul
CPP Module
All of C++98
Class
Inheritance
Diamond Inheritance
virtual
override

Subjects

โ€ข
โ€ข

1. ex00 (Aaaaand... OPEN!)

Base Class

์ „์ฒด์ ์ธ ๋‚ด์šฉ์„ ์ญ‰ ํ›‘์–ด๋ดค๋‹ค๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, ์ด๋ฒˆ Module 03์€ ์ƒ์†์— ๋Œ€ํ•œ ๊ตฌํ˜„์ด๋‹ค. ํด๋ž˜์Šค์˜ ์ƒ์†์€ ๋Œ€์ฒด์ ์œผ๋กœ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ ํ•  ์ผ๋“ค์ด ๊ฝค ๋งŽ๋‹ค. ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ๊ณ ๋ ค๊ฐ€ ๋น ์ง€๊ฒŒ ๋˜๋ฉด, ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋ฅผ ๊ณ ์น˜๋Š”๋ฐ ๋งŽ์€ ์‹œ๊ฐ„์„ ์Ÿ๊ฒŒ ๋œ๋‹ค. ๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„ ๋ฌธ์ œ์—์„œ ์ฃผ์–ด์ง„ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์ธ ClapTrap ํด๋ž˜์Šค๋Š” ๊ทธ๋‚˜๋งˆ ๋‚ด์šฉ์ด ๋งŽ์ง€๋Š” ์•Š๋‹ค.
๋‹ค๋ฅธ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋‚˜ ๋ฉค๋ฒ„ ํ•จ์ˆ˜์— ๋Œ€ํ•ด์„œ๋Š” ๋ฌธ์ œ์—์„œ ์ œ์‹œ๋œ ๋Œ€๋กœ ํ•˜๋ฉด ๋˜๊ณ , ๊ณ ๋ฏผํ•ด๋ณผ ์‚ฌํ•ญ์€ ๊ฐ ํด๋ž˜์Šค์˜ ์†์„ฑ์„ ์œ ์ง€ํ•  ๋ฐฉ๋ฒ•์ด๋‹ค. ๋‹น์žฅ Repair ๊ธฐ๋Šฅ ๋•Œ๋ฌธ์— HP์˜ ์ƒํ•œ์น˜๋ฅผ ์„ค์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ๊ณ , ์ถ”ํ›„์— ํŒŒ์ƒ ํด๋ž˜์Šค๊ฐ€ ๋ณ„๋„์˜ Overriding ์—†์ด ClapTrap์˜ Repair๋ฅผ ์ด์šฉํ•œ๋‹ค๋ฉด ํŒŒ์ƒ ํด๋ž˜์Šค ๋งŒ์˜ HP, EP, AD์˜ ์†์„ฑ์„ ๊ฒฐ์ •์ง€์„ ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ๋งŒ์ผ ์ด์™€ ๊ฐ™์€ ์„ค์ •์ด ์ƒ๋žต๋œ๋‹ค๋ฉด, ํŒŒ์ƒ ํด๋ž˜์Šค ์ž„์—๋„ ClapTrap ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ฐ’์œผ๋กœ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ๋  ์ˆ˜ ์žˆ๋‹ค.
๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฟ ์žˆ๊ฒ ์ง€๋งŒ, ํด๋ž˜์Šค๋งˆ๋‹ค ๊ณ ์œ ํ•œ ์†์„ฑ ๊ฐ’์„ ๋ถ€์—ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ static const ๊ฐ’์œผ๋กœ ์ฃผ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๊ณ , ๋‹จ์ˆœํžˆ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ๋‘์–ด ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ๋Š” ๊ทธ ๊ฐ’์„ ๋ฎ์–ด ์จ์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
๋‘ ๋ฐฉ๋ฒ• ๋ชจ๋‘ ์†์„ฑ ๊ฐ’์„ ์ƒ์† ๋ฐ›์„ ๋•Œ ํŒŒ์ƒ ํด๋ž˜์Šค ๋‚ด๋ถ€์— ์œ„์น˜์‹œ์ผœ ์ด์šฉํ•˜๋Š” ์ ์€ ๋™์ผํ•˜์ง€๋งŒ ์•ฝ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. static const์˜ ๊ฒฝ์šฐ ํŒŒ์ƒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค static const ๊ฐ’์„ ์ •์˜ํ•˜๊ณ  ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์œ„ํ•œ getter, setter๋ฅผ ์ •์˜ํ•ด์•ผ ํ•˜์ง€๋งŒ, ๊ฐ ํด๋ž˜์Šค๋งˆ๋‹ค ๊ทธ ๊ฐ’์„ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Scope ์—ฐ์‚ฐ์ž์ธ ::๋กœ ํ•„์š”ํ•œ ์†์„ฑ์— ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค. ํ›„์ž์˜ ๊ฒฝ์šฐ์—๋Š” ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ ์ •์˜ํ•œ getter, setter๋ฅผ ์ด์šฉํ•˜๋ฏ€๋กœ ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ ์ผ์ผ์ด ์ด๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š์•„๋„ ๋˜์ง€๋งŒ, ํŒŒ์ƒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค ์†์„ฑ ๊ฐ’์„ ๋ฎ์–ด ์”Œ์šฐ๋ฏ€๋กœ ํŠน์ • ๊ฐ’์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— Scope ์—ฐ์‚ฐ์ž๋กœ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
๋‚ด ๊ฒฝ์šฐ์—๋Š” getter, setter๋ฅผ ํด๋ž˜์Šค๋งˆ๋‹ค ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ฝ”๋“œ๋ฅผ ๋„ˆ๋ฌด ๊ธธ๊ฒŒ ์ž‘์„ฑํ•ด์•ผ ํ•ด์„œ ํ›„์ž์˜ ๋ฐฉ๋ฒ•์„ ํƒํ•˜์˜€๋‹ค. ์ด ๋•Œ ํŒŒ์ƒ ํด๋ž˜์Šค๋กœ ๊ฐˆ ๋•Œ๋งˆ๋‹ค ์†์„ฑ ๊ฐ’์„ ๋ฎ์–ด ์”Œ์›Œ์ง€๋ฉด์„œ ํŠน์ • ์†์„ฑ ๊ฐ’์ด ํ•„์š”ํ•  ๋•Œ๋Š” #define์œผ๋กœ ์ •์˜๋œ ๊ฐ’์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค.

2. ex01 - ex02

Protected on Base Class

์ด์ „ ํ•ญ๋ชฉ์—์„œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๊ฐ€ ์ •์˜๋˜์—ˆ๋‹ค๋ฉด, ์ด๋ฅผ ์ƒ์†ํ•˜์—ฌ ScavTrap ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค. ScavTrap ํด๋ž˜์Šค์—์„œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ ์ •์˜๋œ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ private์— ์ •์˜ํ•œ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์„ ๋ชจ๋‘ protected๋กœ ์˜ฎ๊ฒจ์ค˜์•ผ ํ•œ๋‹ค.

Constructor on Derived Class

๋‚ด ๊ฒฝ์šฐ์— ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ฐ’์€ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋„๋ก ๋งŒ๋“ค์—ˆ์œผ๋ฏ€๋กœ, #define์œผ๋กœ ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ฐ’์„ ๋‘๊ณ  ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์—์„œ ๊ธฐ์กด ์†์„ฑ ๊ฐ’์„ ๊ฐฑ์‹ ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
#define์œผ๋กœ ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ฐ’์„ ์ •์˜ํ•˜์ง€ ์•Š๊ณ  ์ƒ์„ฑ์ž์—์„œ ๊ฐ’์„ ์ง์ ‘ ๋ช…์‹œํ•ด๋„ ๋˜๋Š”๋ฐ, ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ์†์„ฑ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์ผ๊ด„์ ์ธ ๋ณ€๊ฒฝ์ด ๋˜์ง€ ์•Š์•„ ์ฝ”๋“œ์˜ ์ ์‘์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.

Virtual for Up Casting

๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ protected๋กœ ์˜ฎ๊ธด ๋’ค์—, ์ƒ์†๋œ ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ Overridingํ•˜๋ ค๋Š” ํ•จ์ˆ˜๋“ค์„ virtual๋กœ ์„ ์–ธํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. virtual๋กœ ์„ ์–ธํ•˜์ง€ ์•Š์•˜๋‹ค๊ณ  ํ•ด์„œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์— ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ Overriding ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ํ•ด๋‹น ํ•จ์ˆ˜๋“ค์„ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ virtual ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•œ ์ด์œ ๋Š” ์—… ์บ์ŠคํŒ… ๋•Œ๋ฌธ์ด๋‹ค.
ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜์—ฌ ํŒŒ์ƒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ, ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋“ค๊ณผ ํŒŒ์ƒ ํด๋ž˜์Šค๋“ค์€ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ๋กœ ๋ฌถ์–ด์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด๋ฅผ ์—… ์บ์ŠคํŒ…์ด๋ผ ํ•œ๋‹ค. ์ด ๋•Œ ํŒŒ์ƒ ํด๋ž˜์Šค๋ฅผ ์—… ์บ์ŠคํŒ… ํ•˜์—ฌ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค ํฌ์ธํ„ฐ๋กœ ํŒŒ์ƒ ํด๋ž˜์Šค์˜ Overridingํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ ค ํ•˜๋ฉด ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ํ˜ธ์ถœ ์‹œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋กœ ํƒ€์ž…์„ ์ธ์‹ํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ธ๋ฐ, ์ด๋ฅผ ๊ทน๋ณตํ•˜์—ฌ ํŒŒ์ƒ ํด๋ž˜์Šค ํƒ€์ž…์„ ์ •์ƒ์ ์œผ๋กœ ์ธ์‹์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„  ๋Ÿฐ ํƒ€์ž„์— ์ž์‹ ์ด ํŒŒ์ƒ ํด๋ž˜์Šค ๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด virtual ํ‚ค์›Œ๋“œ์ด๋‹ค.
์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์™€ ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ๊ตฌ์กฐ๋ฅผ ์ฐพ์•„๋ณด๋ฉด, ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๊ฐ€ ํŒŒ์ƒ ํด๋ž˜์Šค ์œ„์— ๊ทธ๋ ค์ง„ ๋ชจ์Šต์„ ๋งŽ์ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด ๋•Œ ํŒŒ์ƒ ํด๋ž˜์Šค๊ฐ€ ๊ทธ ์œ„์— ์žˆ๋Š” ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ๋กœ ์บ์ŠคํŒ… ๋˜๋ฏ€๋กœ ์—… ์บ์ŠคํŒ…์ด๋ผ ํ•œ๋‹ค. ๋ฐ˜๋Œ€๋กœ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋ฅผ ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ๋กœ ์บ์ŠคํŒ…ํ•˜๋Š” ๋‹ค์šด ์บ์ŠคํŒ…๋„ ์žˆ๋Š”๋ฐ, ์ด๋Š” ์—ฌ๊ธฐ์„œ ๋‹ค๋ฃจ์ง€ ์•Š์œผ๋ฏ€๋กœ ์ง์ ‘ ์ฐพ์•„๋ณด๊ธธ ๋ฐ”๋ž€๋‹ค. ๋‹ค์šด ์บ์ŠคํŒ…์€ dynamic_cast<T>์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค.
๋ฉค๋ฒ„ ํ•จ์ˆ˜๋“ค์€ ํด๋ž˜์Šค ๋‚ด์— ๊ท€์†๋˜๋Š” ์—”ํŠธ๋ฆฌ๋ฅผ ๊ฐ–๋Š”๋ฐ, virtual ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธ๋œ ํ•จ์ˆ˜๋“ค์€ ํด๋ž˜์Šค ๋‚ด์— ์—”ํŠธ๋ฆฌ๋ฅผ ๊ฐ–์ง€ ์•Š๋Š”๋‹ค. virtual ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธ๋œ ํ•จ์ˆ˜๋“ค์€ vTable (Virtual Table)์— ์ž์‹ ์˜ ํƒ€์ž…๊ณผ ๋ฌถ์–ด์„œ ๋ณ„๋„์˜ ์—”ํŠธ๋ฆฌ๋ฅผ ์œ ์ง€ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋Ÿฐ ํƒ€์ž„ ๋„์ค‘์— ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ ค ํ–ˆ์„ ๋•Œ ํด๋ž˜์Šค ๋‚ด์— ์—”ํŠธ๋ฆฌ๊ฐ€ ์—†๋Š” ๊ฒƒ์ด ์ธ์‹๋˜๋ฉด, vTable์—์„œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ๊ฐ€ ์‹ค์ œ๋กœ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ ํ™•์ธํ•œ ๋’ค์— ํƒ€์ž…์— ๋งž๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ๋กœ ์ผ๋ฐ˜ํ™”ํ•˜์—ฌ ๊ฐ ์ƒ์† ๊ฐ์ฒด๋“ค์„ ์šด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ต‰์žฅํžˆ ์œ ์šฉํ•œ๋ฐ, ์ด๋ฅผ ์ด์šฉํ•  ๋•Œ ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด Overridingํ•˜๋ ค๋Š” ํ•จ์ˆ˜๋“ค์„ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ ๋ฐ˜๋“œ์‹œ virtual๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์ž.

Overriding?

ํ˜„์žฌ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋Š” ์„œ๋ธŒ์ ํŠธ๋Š” C++98์ด๋ผ ํ•ด๋‹น๋˜์ง€ ์•Š์ง€๋งŒ, C++11๋ถ€ํ„ฐ๋Š” override๋ผ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค. ํ•ด๋‹น ํ‚ค์›Œ๋“œ๋ฅผ ๋ช…์‹œํ•œ ํ•จ์ˆ˜๋Š” ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ ์ด๋ฏธ ์ •์˜๋œ ํ•จ์ˆ˜์™€ ๋‹ค๋ฅธ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋กœ ์„ ์–ธ๋œ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ†ตํ•ด ์˜ค๋ฅ˜ ๋ฌธ๊ตฌ๋ฅผ ๋ฐ›์œผ๋ฉด์„œ ์‚ฌ์ „์— ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, override ํ‚ค์›Œ๋“œ์˜ ์—ญํ• ์€ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํŠน์ • ํ•จ์ˆ˜๋ฅผ Overriding ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹œ์ ์œผ๋กœ ์•Œ๋ฆฌ๋Š”๋ฐ ์žˆ๋‹ค.
#include <iostream> class A { public: virtual void scream(void) { std::cout << "hi" << std::endl; } }; class B : public A { public: void scream(void) const { std::cout << "hello" << std::endl; } }; int main(void) { B b; A *p = &b; b.scream(); p->scream(); return (0); }
C++
์˜ˆ๋ฅผ ๋“ค์–ด ์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์ด AA ํด๋ž˜์Šค์™€ ์ด๋ฅผ ์ƒ์† ๋ฐ›์€ BB ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ณด์ž. ๋‘ ํด๋ž˜์Šค์˜ scream ํ•จ์ˆ˜๋Š” ๋™์ผํ•˜๊ฒŒ ์ •์˜๋˜์–ด Overriding ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋‚˜, ๋ฉค๋ฒ„ ํ•จ์ˆ˜์˜ const ์œ ๋ฌด์— ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. main ํ•จ์ˆ˜๋ฅผ ๋ณด๋ฉด BB ํด๋ž˜์Šค ๊ฐ์ฒด ๊ทธ๋Œ€๋กœ scream์„ ํ˜ธ์ถœํ•œ ๊ฒฝ์šฐ์™€ AA ํด๋ž˜์Šค๋กœ ์—… ์บ์ŠคํŒ… ํ›„์— scream์„ ํ˜ธ์ถœํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ •์ƒ์ ์œผ๋กœ Overriding๊ฐ€ ๋˜์—ˆ๋‹ค๋ฉด ๋‘ ํ•จ์ˆ˜ ๋ชจ๋‘ hello๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” hello์™€ hi๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.
๋ฌผ๋ก  ์„œ๋ธŒ์ ํŠธ์—์„œ ๋ช…์‹œ๋œ ๊ฒƒ์ฒ˜๋Ÿผ -Wall -Wextra -Werror๋ฅผ ์ด์šฉํ•˜๋ฉด ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ๊ฒฝ๊ณ ๋ฅผ ๋‚ด์ฃผ๊ธด ํ•˜์ง€๋งŒ, ํ•ด๋‹น ํด๋ž˜์Šค ๋‚ด์—๋Š” scream ํ•จ์ˆ˜ ์™ธ์—๋„ ์˜๋„์ ์œผ๋กœ ์œ„์ฒ˜๋Ÿผ ๊ตฌ๋ถ„์ง€์€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ช…ํ™•ํ•˜๊ฒŒ Overriding์„ ํ•œ ๊ฒƒ์ธ์ง€ ์•„๋‹Œ์ง€ override ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ๊ตฌ๋ถ„์ง€์„ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
#include <iostream> class A { public: virtual void scream(void) { std::cout << "hi" << std::endl; } }; class B : public A { public: void scream(void) const override { std::cout << "hello" << std::endl; } }; int main(void) { B b; A *p = &b; b.scream(); p->scream(); return (0); }
C++
override ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ฒŒ ๋˜๋ฉด, ์ปดํŒŒ์ผ ์‹œ์— ์œ„์™€ ๊ฐ™์ด ๋ช…ํ™•ํ•˜๊ฒŒ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ช…์‹œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋งŒ๋“œ๋Š” ์‹ค์ˆ˜๋ฅผ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŽ์€ ๋„์›€์„ ์ค€๋‹ค. ๋”ฐ๋ผ์„œ C++11 ์ด์ƒ์„ ์‚ฌ์šฉํ•  ์ผ์ด ์žˆ๋‹ค๋ฉด, override ํ‚ค์›Œ๋“œ๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์ด์šฉํ•˜์ž.

Virtual Destructor?

Overriding ํ•˜๋ ค๋Š” ํ•จ์ˆ˜๋“ค์„ virtual๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ์ค‘์š”ํ•œ ์Šต๊ด€์ด ํ•˜๋‚˜ ๋” ์žˆ๋‹ค. ์†Œ๋ฉธ์ž๋ฅผ virtual ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด ์—ญ์‹œ๋„ ์—… ์บ์ŠคํŒ…๊ณผ ๊ด€๋ จ์ด ์žˆ๋‹ค.
์ด์ „ ํ•ญ๋ชฉ์—์„œ ์„ค๋ช…ํ•œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ๋กœ ์ƒ์† ๊ฐ์ฒด๋“ค์„ ์ง์ ‘ ์ƒ์„ฑํ•˜์—ฌ ์‹คํ–‰ํ•ด๋ณด๋ฉด Overriding ํ•จ์ˆ˜๋“ค์„ ์ •์ƒ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์ง€๋งŒ, ์ƒ์† ๊ฐ์ฒด์˜ ์†Œ๋ฉธ์ž ๋‚ด์—์„œ ์ถœ๋ ฅ๋ฌธ์„ ๋‘์–ด ํ™•์ธํ–ˆ์„ ๋•Œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž๋งŒ ํ˜ธ์ถœ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค AA์™€ ํŒŒ์ƒ ํด๋ž˜์Šค BB๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ณด์ž. ์ •์ƒ์ ์ธ ์ƒ์„ฑ ๋ฐ ์†Œ๋ฉธ์€ AA ์ƒ์„ฑ โ†’ BB ์ƒ์„ฑ โ†’ B ์†Œ๋ฉธ โ†’ AA ์†Œ๋ฉธ์ธ๋ฐ, ์—… ์บ์ŠคํŒ…ํ•˜์—ฌ ์ด์šฉํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ์ž๋ฅผ virtual๋กœ ๋‘์ง€ ์•Š์•˜์„ ๋•Œ๋Š” AA ์ƒ์„ฑ โ†’ BB ์ƒ์„ฑ โ†’ AA ์†Œ๋ฉธ์˜ ๊ฒฐ๊ณผ๋งŒ ์–ป๊ฒŒ ๋œ๋‹ค. ์ž์นซํ•˜๋ฉด BB๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ๋˜์ง€ ์•Š์•„ ๋ˆ„์ˆ˜๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์†Œ๋ฉธ์ž๋„ virtual๋กœ ์„ ์–ธํ•จ์œผ๋กœ์จ, ๋Ÿฐ ํƒ€์ž„์— ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๊ฐ’์ด ์‹ค์ œ๋กœ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ ํ™•์ธํ•˜๊ณ  ํƒ€์ž…์— ํ•ด๋‹น๋˜๋Š” ์†Œ๋ฉธ์ž๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

3. ex03 (Now itโ€™s weird!)

Diamond Inheritance

๋‹ค์ด์•„๋ชฌ๋“œ ์ƒ์†์€ ์œ„์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค. Module 03์˜ ๊ฐ€์žฅ ํ•ต์‹ฌ์ ์ธ ๋ถ€๋ถ„์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์ „ ํ•ญ๋ชฉ๊นŒ์ง€ ๊ตฌํ˜„๋œ ClapTrap ํด๋ž˜์Šค, FragTrap ํด๋ž˜์Šค, ScavTrap ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ DiamondTrap ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ex03์˜ ๋ชฉํ‘œ์ธ๋ฐ, DiamondTrap ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ FragTrap ํด๋ž˜์Šค์™€ ScavTrap ํด๋ž˜์Šค๋ฅผ ๊ทธ๋ƒฅ ๋ฐ”๋กœ ์ƒ์†ํ•ด๋ฒ„๋ฆฌ๋ฉด ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์€ ๋‹ค์ด์•„๋ชฌ๋“œ ์ƒ์†์ด ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š”๋‹ค.
Class DiamiondTrap : public FragTrap, public ScavTrap { /* If there's no revision on FragTrap & ScavTrap ** A A ** | | ** B C ** \-------------/ ** | ** | ** D */ };
C++
DiamondTrap ํด๋ž˜์Šค๋Š” FragTrap ํด๋ž˜์Šค์™€ ScavTrap ํด๋ž˜์Šค๋ฅผ ๊ฐ๊ฐ ์ƒ์† ๋ฐ›์€ ๋‹ค์ค‘ ์ƒ์† ๊ฐ์ฒด์ธ๋ฐ, DiamondTrap ํด๋ž˜์Šค์˜ ๋‘ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์ฝ”๋“œ๋ฅผ ๋ณ„๋„๋กœ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์œ„์™€ ๊ฐ™์ด ์ƒ์†์„ ๋ฐ›์œผ๋ฉด ์ตœ์ƒ์œ„์— ์กด์žฌํ•˜๋Š” ClapTrap ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๊ฐ€ 2๋ฒˆ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ตœ์ดˆ์— ์ œ์‹œ๋œ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋‹ค์ด์•„๋ชฌ๋“œ ์ƒ์†์ด ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ฃผ์„์— ๋ณด์ด๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๊ฐ€ ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค.
์ฃผ์„๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๊ฐ€ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์ด์œ ๋Š” ์ตœ์ƒ์œ„ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์ธ ClapTrap ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์ ‘๊ทผํ•˜๋ ค ํ•  ๋•Œ ํ•ด๋‹น ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๊ฐ€ ์ค‘๋ณต์œผ๋กœ ์กด์žฌํ•˜๋ฏ€๋กœ ์–ด๋Š ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ์ ‘๊ทผํ•  ์ง€ Ambiguity (๋ชจํ˜ธ์„ฑ)์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฒˆ ์„œ๋ธŒ์ ํŠธ์—์„œ DiamondTrap ํด๋ž˜์Šค์—๊ฒŒ ์›ํ•˜๋Š” ์‚ฌํ•ญ ์ค‘ ํ•˜๋‚˜๋Š” ClapTrap ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๊ฐ€ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด FragTrap ํด๋ž˜์Šค ํ˜น์€ ScavTrap ํด๋ž˜์Šค ํ•˜๋‚˜๋งŒ ์ƒ์† ๋ฐ›๊ธฐ์—๋Š” ์ƒํ™ฉ์ด ์—ฌ์˜์น˜ ์•Š๋‹ค. ์–ด๋–ป๊ฒŒ ์ด๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ?

Virtual Inheritance

์œ„์—์„œ ์ œ์‹œ๋œ ์‚ฌ๋ญ‡ ๋‹ค๋ฅธ ๊ตฌ์กฐ๋Š” virtual ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์ „์— ์†Œ๊ฐœํ•œ virtual ํ‚ค์›Œ๋“œ์™€ ๋™์ผํ•˜์ง€๋งŒ ๊ธฐ๋Šฅ์€ ์‚ฌ๋ญ‡ ๋‹ค๋ฅด๋‹ค. ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ Overriding ํ•˜๋ ค๋Š” ํ•จ์ˆ˜๋ฅผ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ virtual๋กœ ์„ ์–ธํ•˜๋ฉด ์—… ์บ์ŠคํŒ… ์‹œ์— ์ž์‹ ์˜ ํƒ€์ž…์— ๋งž๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ, ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ virtual ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘์ฒฉ๋  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋ฅผ ๋ช…์‹œํ•˜๋ฉด ๋‹ค์ค‘ ์ƒ์† ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ค‘๋ณต์œผ๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
ํ•จ์ˆ˜์˜ Overriding์—์„œ virtual ํ•จ์ˆ˜๋“ค์€ vTable์— ์กด์žฌํ•˜์—ฌ vptr (Virtual Pointer)๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋‹ค์ค‘ ์ƒ์† ๊ฐ์ฒด์— ๋Œ€ํ•œ virtual ํ‚ค์›Œ๋“œ๋“ค ์—ญ์‹œ vptr์„ ์ด์šฉํ•˜์—ฌ vTable์— ์ ‘๊ทผํ•˜๋ฉด์„œ virtual๋กœ ๋ช…์‹œํ•œ ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ๋‘ virtual ํ‚ค์›Œ๋“œ์˜ ๊ธฐ๋Šฅ์ด ๋‹ค๋ฅด๊ฒŒ ๋ณด์ด์ง€๋งŒ ๊ทธ ๋™์ž‘์€ vptr๊ณผ vTable์„ ๊ณตํ†ต์ ์œผ๋กœ ์ด์šฉํ•œ๋‹ค.
์ฐธ๊ณ ๋กœ vTable์€ ๊ตฌํ˜„๋œ ํด๋ž˜์Šค๋งˆ๋‹ค ์ •์ ์ธ ํ˜•ํƒœ๋กœ ๊ฐ๊ฐ ์กด์žฌํ•œ๋‹ค.
์ด์— ๋Œ€ํ•ด์„œ ์กฐ๊ธˆ ๋” ์–ธ๊ธ‰ํ•˜์ž๋ฉด, virtual์ด ๋ช…์‹œ๋œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋ฅผ ์ƒ์† ๋ฐ›์€ ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ Invariant Region๊ณผ Shared Region์œผ๋กœ ๋‚˜๋‰œ๋‹ค. Invariant Region์€ ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ๊ณ ์ •๋œ ์œ„์น˜ ๊ฐ’์„ ๋ฐ›์•„ ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ ๊ณต๊ฐ„์„ ์˜๋ฏธํ•˜๋ฉฐ, ์ด๋ฒˆ ์„œ๋ธŒ์ ํŠธ์—์„œ๋Š” DiamondTrap ํด๋ž˜์Šค, FragTrap ํด๋ž˜์Šค, ClapTrap ํด๋ž˜์Šค๊ฐ€ ํ•ด๋‹น๋œ๋‹ค. ๋ฐ˜๋ฉด Shared Region์˜ ๊ฒฝ์šฐ virtual๋กœ ๋ช…์‹œ๋œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋กœ์จ ClapTrap ํด๋ž˜์Šค๊ฐ€ ํ•ด๋‹น๋˜๋ฉฐ, ์ด ๊ณต๊ฐ„์€ ํŒŒ์ƒ ํด๋ž˜์Šค๋“ค์— ์˜์กด์ ์œผ๋กœ ์œ ๋™์„ฑ์„ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์— ์ง์ ‘์ ์ธ ์ ‘๊ทผ์ด ๋˜์ง€ ์•Š๋Š” ๊ณต๊ฐ„์ด๋‹ค. ๋‘ ๊ณต๊ฐ„์€ ํด๋ž˜์Šค๋ฅผ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์—ˆ์„ ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๋ ˆ์ด์•„์›ƒ์—์„œ ๋ช…ํ™•ํ•˜๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋Œ€์ฒด์ ์œผ๋กœ Invariant Region์€ ๊ฐ์ฒด ์‹œ์ž‘ ์ฃผ์†Œ ์ชฝ์— ์œ„์น˜ํ•˜๊ณ  Shared Region์€ ๊ทธ ๋ ์ชฝ ์ฃผ์†Œ์— ์œ„์น˜ํ•˜๊ฒŒ ๋œ๋‹ค.
์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ๊ธ€๋“ค์„ ์ฐธ๊ณ ํ•ด๋ณด๋ฉด ๋งŽ์€ ๋„์›€์ด ๋œ๋‹ค.
class FragTrap : virtual public ClapTrap { // ... implementation }; class ScavTrap : virtual public ClapTrap { // ... implementation };
C++
์„œ๋ก ์ด ๊ธธ์—ˆ๋Š”๋ฐ, ๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๊ฐ€ ์ค‘์ฒฉ๋˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด์„  FragTrap ํด๋ž˜์Šค์™€ ScavTrap ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ ์œ„์™€ ๊ฐ™์ด ClapTrap ํด๋ž˜์Šค๋ฅผ virtual๋กœ ์ƒ์†ํ•œ๋‹ค๊ณ  ๋ช…์‹œํ•˜๋ฉด ๋œ๋‹ค.

Constructor Calling Order of Base Class

ClapTrap ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•  ๋•Œ virtual ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ–ˆ๋‹ค๋ฉด ๊ฑฐ์˜ ๋๋‚œ ๊ฒƒ๊ณผ ๋‹ค๋ฆ„ ์—†๋‹ค. ์„œ๋ธŒ์ ํŠธ์—์„œ๋Š” DiamondTrap ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์ƒ์† ์ˆœ์„œ๋ฅผ FragTrap ํด๋ž˜์Šค ์ด ํ›„ ScavTrap ํด๋ž˜์Šค๋กœ ์ œ์‹œํ–ˆ๋Š”๋ฐ, ์ด ์ƒ์† ์ˆœ์„œ๋Š” DiamondTrap ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋ฅผ ์ •์˜ํ•˜๊ณ  ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ˆœ์„œ์— ํฐ ์˜ํ–ฅ์„ ๋ผ์นœ๋‹ค.
class A { // ... implementation }; class B : virtual public A { // ... implementation }; class C : virtual public A { // ... implementation }; class D : public C, public B { // ... implementation };
C++
๋‹ค์ค‘ ์ƒ์† ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๊ฐ€ ์—ฌ๋Ÿฟ ์กด์žฌํ•  ๋•Œ ์ด๋“ค์„ ์–ด๋–ค ์ƒ์„ฑ์ž๋กœ ํ˜ธ์ถœํ• ์ง€๋Š” ํฌ๊ฒŒ ์ค‘์š”ํ•˜์ง€ ์•Š์ง€๋งŒ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ˆœ์„œ๋Š” ์ค‘์š”ํ•˜๋‹ค. ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋กœ ์ฃผ์–ด์ ธ ์žˆ๋‹ค๋ฉด, ์ƒ์„ฑ์ž ํ˜ธ์ถœ ์ˆœ์„œ๋Š” AA โ†’ BB โ†’ CC ์ˆœ์„œ๋ฅผ ์ง€์ผœ์•ผ ํ•œ๋‹ค. ์ด ๋•Œ ํŠน์ • ์ƒ์„ฑ์ž๋ฅผ ์ƒ๋žตํ•˜์—ฌ AA โ†’ CC, BB โ†’ CC, AA โ†’ CC๋กœ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ๋Š” ์ƒ๋žต๋œ ํด๋ž˜์Šค์˜ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋ฏ€๋กœ ํฐ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.
// Error 1 DiamondTrap::DiamondTrap(void) : FragTrap(), ScavTrap(), ClapTrap() // Error 2 DiamondTrap::DiamondTrap(void) : ScavTrap(), FragTrap()
C++
๋”ฐ๋ผ์„œ DiamondTrap ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋ฅผ ์ •์˜ํ•  ๋•Œ FragTrap ํด๋ž˜์Šค์™€ ScavTrap ํด๋ž˜์Šค์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พผ๋‹ค๊ฑฐ๋‚˜, ClapTrap ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋ฅผ ์ œ์ผ ๋์œผ๋กœ ๋ฏธ๋Š” ๋“ฑ ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.
์ด ์™ธ์˜ ์ฃผ์˜ํ•  ์  ๋ฐ ์ƒ์†์˜ ๊ธฐ๋ณธ ๊ฐœ๋…์€ ์•„๋ž˜ ๋งํฌ์—์„œ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Using Specific Scope

virtual ํ‚ค์›Œ๋“œ๋กœ ์ตœ์ƒ์œ„ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ Ambiguity๋ฅผ ํ•ด๊ฒฐ ํ–ˆ์ง€๋งŒ, ex03๊ณผ ๊ฐ™์ด ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์™€ ๋™์ผํ•œ ์ด๋ฆ„์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์—ฌ์ „ํžˆ Ambiguity๊ฐ€ ๋‚จ๊ฒŒ ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด _name์ด๋ผ๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” ClapTrap ํด๋ž˜์Šค์—๋„ ์กด์žฌํ•˜๊ณ  DiamondTrap ํด๋ž˜์Šค์—๋„ ์กด์žฌํ•œ๋‹ค. ์ตœ๊ทผ ์ด์šฉํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋˜‘๋˜‘ํ•ด์„œ DiamondTrap ๋‚ด์—์„œ _name์„ ์ด์šฉํ•˜๋ฉด DiamondTrap์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ์ธ์‹ํ•˜๋Š”๋ฐ, ๊ทธ๋ ‡๋‹ค๋ฉด ClapTrap์˜ _name์„ ์ด์šฉํ•  ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ? ํ•ด๊ฒฐ๋ฒ•์€ Scope ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•˜์—ฌ ClapTrap::_name์œผ๋กœ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.
์—… ์บ์ŠคํŒ…์„ ์†Œ๊ฐœํ•˜๋ฉด์„œ virtual ํ•จ์ˆ˜๊ฐ€ ์ž๊ธฐ ์ž์‹ ์—๊ฒŒ ๋งž๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์–˜๊ธฐ๋ฅผ ๋“ค์—ˆ์„ ๋•Œ, ๋ณ€์ˆ˜๋„ ๊ฐ€๋Šฅํ• ๊นŒ๋ผ๊ณ  ์˜๋ฌธ์„ ๊ฐ€์กŒ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ์—๋Š” Scope ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•˜์—ฌ ์ง์ ‘ ์›ํ•˜๋Š” Scope์˜ ๋ณ€์ˆ˜๋ฅผ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ex03์˜ DiamondTrap ํด๋ž˜์Šค๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์™€ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํŠน์ • ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ๊ฒƒ์œผ๋กœ ์ด์šฉํ•˜๋ผ๋Š” ๋ช…์‹œ๊ฐ€ ๋˜์–ด ์žˆ๋Š”๋ฐ, ์ด๋ฅผ Scope ์—ฐ์‚ฐ์ž๋กœ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•˜๋Š”์ง€ ํ•˜๋‚˜ ํ•˜๋‚˜ ์•Œ์•„๋ณด์ž.
// Solution 1 class DiamondTrap : public FragTrap, public ScavTrap { private: // ... implementation public: using ScavTrap::attack; // ... implementation }; // Solution 2 void DiamondTrap::attack(void) { ScavTrap::attack(); }
C++
๋ฉค๋ฒ„ ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ Scope ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•˜๋ฉด ๋˜๋Š”๋ฐ, Scope ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. ์ฒซ ์งธ๋Š” ํด๋ž˜์Šค ์ •์˜ ์‹œ using ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŠน์ • Scope์˜ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค๊ณ  ๋ช…์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ณ , ๋‘˜ ์งธ๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ์ •์˜ํ•˜์—ฌ ๊ทธ ์•ˆ์— Scope์˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
// Solution 1 // Attributes of Base Class implemented by static const class DiamondTrap : public FragTrap, public ScavTrap { private: // ... implementation public: using ScavTrap::attack; using FragTrap::_hp; using ScavTrap::_ep; using FragTrap::_ad; // ... implementation }; // Solution 2 // Attributes of Base Class implemented by Member Variables DiamondTrap::DiamondTrap(...) : ... { _hp = F_HP; _ep = S_EP; _ad = F_AD; }
C++
DiamondTrap ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” ๊ธฐ์กด์— ์ž‘์„ฑํ•œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ํ˜•ํƒœ์— ๋”ฐ๋ผ์„œ ์„ค์ • ๋ฐฉ๋ฒ•์ด ๋‹ฌ๋ผ์ง„๋‹ค. ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ ์†์„ฑ ๊ฐ’์„ static const๋กœ ์œ ์ง€ํ•œ ๊ฒฝ์šฐ์—๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜์—์„œ ์ด์šฉํ•œ using ํ‚ค์›Œ๋“œ๋ฅผ ๋ช…์‹œํ•˜์—ฌ ํŠน์ • Scope์˜ ์†์„ฑ ๊ฐ’์„ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์—์„œ ์†์„ฑ ๊ฐ’์„ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ์œ ์ง€ํ•œ ๊ฒฝ์šฐ์—๋Š” ๋‹ค์ค‘ ์ƒ์† ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ FragTrap ํด๋ž˜์Šค์™€ ScavTrap ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ํ˜ธ์ถœ์— ๋”ฐ๋ผ ๊ทธ ๊ฐ’์ด ๊ฐฑ์‹  ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํŠน์ • Scope์˜ ๊ฐ’์„ ์ด์šฉํ•˜๋ผ๊ณ  ๋ช…์‹œํ•ด๋„ ์ด๋ฏธ ๊ทธ ๊ฐ’์ด ๊ฐฑ์‹ ๋˜์–ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ํ˜ธ์ถœํ•œ ScavTrap์˜ ์†์„ฑ ๊ฐ’์œผ๋กœ ์ด์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ์ด ๋•Œ๋Š” DiamondTrap ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ๋‚ด์—์„œ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ๋‚˜ํƒ€๋‚œ ์†์„ฑ ๊ฐ’์„ ์ง์ ‘ ์„ค์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ๊ธฐ์กด์— ๊ฐ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•œ ํ—ค๋”์—์„œ #define์„ ์ด์šฉํ•˜์—ฌ ์†์„ฑ ๊ฐ’์„ ์ •์˜ํ–ˆ์œผ๋ฏ€๋กœ ์ด๋ฅผ ์ด์šฉํ•˜๋ฉด ์ผ๊ด„์ ์œผ๋กœ ํŠน์ • Scope์˜ ๊ฐ’์„ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

4. Code of Jseo