たけいせい


#include <iostream>

#include<iomanip>

using namespace std;

//다형성

//다형성(Polymorphism = Poly + Morph = 겉은 똑같은데, 기능이 다르게 동작한다

//오버로딩(OverLoading) = 함수 중복 정의, 함수 이름의 재사용

//오버라이딩(OverRiding) = 재정의 = 부모 클래스의 함수를 자식 클래스에서 재정의

//바인딩(Binding) = 묶는다

//-정적 바인딩(Static Binding) : 컴파일 시점에 결정

//-동적 바인딩(Dynamic Binding) : 실행 시점에 결정

//일반 함수는 정적 바인딩을 사용한다.

//동적 바인딩을 원한다면? -> 가상 함수(virtual function)을 사용해야함!

//그런데 실제 객체가 어떤 타입인지 어떻게 알고 알아서 가상함수를 호출해준걸까?

//-가상 함수 테이블(vftable)

//.vftable [] 4바이트 (32) 8바이트(64)

//[호출할 가상함수 주소][호출할 가상함수 주소]

//순수 가상 함수 : 구현은 없고 인터페이스만 전달하는 용도로 사용

//순수 가상함수가 1개 이상 포함되면 바로 추상 클래스로 간주

//-직접적으로 객체를 만들 수 없게 됨

class Player {

public:

 void Move() { cout << "Move Player!" << endl; }

 virtual void VMove() { cout << "VMove Player!" << endl; }

 virtual void VDie() { cout << "VDie Player!" << endl; }

 //순수 가상 함수

 //자식 클래스들은 무조건 이 함수를 재정의해야함

 virtual void VAttack() = 0;

 //void Move(int a) { cout << "Move Player (int)!" << endl; } //오버로딩

public:

 int _hp;

};

class Knight :public Player {

public:

 //가상 함수는 재정의를 하더라도 가상 함수다!

 //virtual을 안붙이더라도 가상함수임

 virtual void VMove(){ cout << "VMove Knight!" << endl; } //오버라이딩

 virtual void VDie() { cout << "VDie Knight!" << endl; }

 virtual void VAttack() {};

public:

 int _stamina;

};

class Mage :public Player {

public:

 virtual void VAttack() {};

public:

 int _mp;

};

//모든 플레이어를 상속하는 개체를 하나의 함수로 처리 가능

//그러나 일반함수는 정적바인딩을 사용하기 때문에 컴파일 시점에서 호출할 함수가 결정됨

//따라서 Knight 든 Player 객체든 무조건 Player객체의 Move함수를 호출

//void MovePlayer(Player* player) {

// player->Move();

//}

//동적 바인딩함수 호출

void MovePlayer(Player* player) {

 player->VMove();

}

int main()

{

 //Player p;

 //p.Move();

 Knight k;

 //k.Move();

 //p.Move(1);

 //MovePlayer(&p); //플레이어는 플레이어이다? Yes

 MovePlayer(&k); //기사는 플레이어이다? Yes

}