**기능은 같지만 세부적인 내용은 다를때
- player의 render(이름, 체력, 공격력)
- monster의 render(체력, 공격력)
**오버라이딩의 조건
- 부모와 자식이라는 상속 관계가 있어야 함
- 부모와 자식에 반환 타입, 이름, 매개변수가 같은 함수가 있어야 함
- 부모의 함수 앞에 virtual 키워드 삽입
class CObj
{
public:
virtual void Render(){cout<< "obj" << endl;};
};
class CPlayer:public CObj
{
public:
void Render(){cout << "player" << endl;};
};
**vptr, vtbl(가상함수 포인터, 가상 함수 테이블)
- 가상 함수들의 목록이 저장된 테이블
- 테이블의 크기는 가상 함수 개수에 따라 커진다
- virtual 키워드는 상속되어 내려가기 때문에 각 클래스마다 vptr과 vtbl을 소유하게 된다.
- 부모 클래스에서 선언된 가상함수가 자식 클래스에 없다면 자식 가상함수 테이블에 자동으로 생성된다.
- vtbl은 같은 클래스의 객체끼리 공유, vptr은 각 개체마다 하나씩 가진다.(같은 vtbl을 가리킴)
**동적 바인딩
- 참조하는 객체가 런타임에 정해짐
- 생성된 객체의 vptr과 vtbl을 참조하여 테이블에 있는 함수를 호출한다.
**오버라이딩의 2가지 개념
- 은닉화 : 자식 클래스는 부모의 vptr을 가지고 있지만 자식의 vptr로 가려진다.
- 재정의 : 부모의 기능을 자식의 클래스에서 세부적으로 다시 정의하여 사용할 수 있다.
**소멸자 오버라이딩
class CBase
{
public:
CBase(){}
virtual ~CBase(){}
};
class CDerived
{
public:
CDerived(){}
~CDerived(){}
};
int main()
{
CBase* ptr = new CDerived;
delete ptr;
}
new로 생성하는 객체는 자식 객체이고 delete로 해제하는 포인터는 부모 클래스의 포인터이기 때문에 소멸자에 virtual을 사용하지 않으면 부모 클래스의 메모리 반환이 이루어지지 않는다.
**오버라이딩의 한계
- 모든 자식들이 부모의 기능이 필요없더라도 소유하게 된다.
**순수 가상함수
오버라이딩을 하기 위한 도구
class CBase 추상 클래스: 객체 생성이 불가능
{
public:
virtual void Render() = 0; 순수 가상함수
CBase(){}
virtual ~CBase(){}
};
class CDerived :public CBase
{
public:
void Render();
CDerived(){}
~CDerived(){}
};
추가적인 키워드
abstract : 추상 클래스를 나타내는 명시적인 표현
final : 마지막 상속 클래스를 나타내는 키워드, final 클래스는 상속이 불가능함
- 순수 가상함수를 하나라도 가지고 있는 클래스를 추상 클래스라고 부른다.
- 추상 클래스는 객체를 생성할 수 없다.
- 상속받은 모든 자식들은 ‘반드시’ 함수의 몸체를 구현해야 한다.