가상 함수(Virtual Function)와 동적 바인딩(Dynamic Binding)
동적 바인딩 : 부모 클래스가 자식 클래스를 가리키고 있으면, 자식 클래스에 오버라이딩된 메서드를 실행할 수 있도록 동적으로 바인딩을 해준다.
참고)
동적 --> 런타임에 결정
정적 --> 컴파일 타임에 결정
Example) RPG 게임에서 무기 구현
#include <iostream>
using namespace std;
class Weapon {
public:
Weapon(int power) : power(power) {
cout << "Weapon(int)" << endl;
}
void Use() {
cout << "Weapon::Use()" << endl;
}
protected:
int power;
};
class Sword : public Weapon {
public:
Sword(int power) : Weapon(power) {
cout << "Sword(int)" << endl;
}
void Use() {
cout << "Sword::Use()" << endl;
Swing();
}
private:
void Swing() {
cout << "Swing sword" << endl;
}
};
class Magic : public Weapon {
public:
Magic(int power, int manaCost) : Weapon(power), manaCost(manaCost) {
cout << "Magic(int, int)" << endl;
}
void Use() {
cout << "Magic::Use()" << endl;
Cast();
}
private:
void Cast() {
cout << "Cast magic." << endl;
}
int manaCost;
};
int main(void) {
Sword mySword(10);
Magic myMagic(15, 7);
mySword.Use();
myMagic.Use();
자식 생성자가 호출되기 전에 반드시 부모 생성자가 호출된다
mySword.Use()의 경우 Sword::Use()가 호출된다
myMagic.Use()의 경우 Magic::Use()가 호출된다
우리가 게임을 할 때 무기로 칼을 사용할 수도 있고, 마법 지팡이를 사용할 수도 있다.
// 메인 함수 이어서
Weapon *currentWeapon;
currentWeapon = &mySword;
currentWeapon->Use();
}
currentWeapon->Use()의 경우 Weapon::Use()가 호출된다
- 정적 바인딩
가상 함수
우리는 내가 들고있는 무기의 Use()를 호출하고 싶다.
- 이를 위해서 virtual 키워드를 사용하기만 하면 된다
class Weapon {
public:
/* 생략 */
virtual void Use() {
cout << "Weapon::Use()" << endl;
}
/* 생략*/
};
int main(void) {
/* 생략 */
Weapon *currentWeapon;
currentWeapon = &mySword;
currentWeapon->Use();
}
- currentWeapon->Use()에서 Sword의 Swing이 호출된다
currentWeapon = &myMagic;
currentWeapon->Use();
- currentWeapon->Use()에서 myMagic의 myMagic이 호출 된다
컴파일러가 가상 함수를 처리하는 방식
currentWeapon->Use()를 보고 부모 클래스의 Use() 함수를 살펴본다
virtual로 선언되있는 것을 보고 가상 함수라는 것을 확인한다
가상 함수란 이 함수가 실행이 될 수도 있고, 안될 수도 있다는 의미를 내포
컴파일러는 컴파일 할 때 virtual 함수를 만나면, 런타임에 바인딩을 결정하도록 미룬다.
- 프로그램을 만드는 시점에는 함수가 실행 될지 안될지 모르기 때문에 프로그램이 실행되는 시점에 결정하게끔 한다.
- 런타임 중에는 currentWeapon이 어떤 타입의 객체를 가리키고 있는지 알 수 있기 때문에, 가리키는 객체 타입에 해당하는 함수가 실행된다
참조) 두들낙서 C/C++ 강좌
'Programming Language > C++' 카테고리의 다른 글
[C++] 순수 가상 함수와 추상 클래스 (0) | 2024.06.27 |
---|---|
[C++] 상속이 필요한 이유(2) (0) | 2024.06.27 |
[C++] 오버라이딩(Overriding)과 정적 바인딩(Static Binding) (0) | 2024.06.27 |
[C++] 상속이 필요한 이유(1) (0) | 2024.06.27 |
[C++] 상속(Inheritance)과 접근제어(Access Control) (0) | 2024.06.27 |